From ceca6959d2a7f258d62ac4f589095b65084706c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 22 Sep 2013 04:21:36 +0200 Subject: Working 1.6 modding (currently only forge) --- logic/BaseInstance.cpp | 2 +- logic/BaseInstance.h | 2 +- logic/ForgeInstaller.cpp | 125 +++++++++++++++++++ logic/ForgeInstaller.h | 25 ++++ logic/LegacyUpdate.cpp | 4 +- logic/ModList.h | 3 + logic/OneSixInstance.cpp | 114 +++++++++-------- logic/OneSixLibrary.cpp | 98 +++++++++++---- logic/OneSixLibrary.h | 26 ++-- logic/OneSixRule.cpp | 66 +++++++++- logic/OneSixRule.h | 6 +- logic/OneSixUpdate.cpp | 85 +++++++------ logic/OneSixVersion.cpp | 261 ++++++++++++++++++++++++++++++++++----- logic/OneSixVersion.h | 60 +++++---- logic/OpSys.cpp | 11 ++ logic/OpSys.h | 1 + logic/VersionFactory.cpp | 196 ----------------------------- logic/VersionFactory.h | 24 ---- logic/lists/ForgeVersionList.cpp | 11 +- logic/lists/ForgeVersionList.h | 52 ++++---- logic/tasks/LoginTask.cpp | 2 +- 21 files changed, 737 insertions(+), 437 deletions(-) create mode 100644 logic/ForgeInstaller.cpp create mode 100644 logic/ForgeInstaller.h delete mode 100644 logic/VersionFactory.cpp delete mode 100644 logic/VersionFactory.h (limited to 'logic') diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index 10bb4573..ec86596a 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -132,7 +132,7 @@ InstanceList *BaseInstance::instList() const return NULL; } -BaseVersionList *BaseInstance::versionList() const +QSharedPointer BaseInstance::versionList() const { return MMC->minecraftlist(); } diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index fa317ba1..374d1437 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -134,7 +134,7 @@ public: * \brief Gets a pointer to this instance's version list. * \return A pointer to the available version list for this instance. */ - virtual BaseVersionList *versionList() const; + virtual QSharedPointer versionList() const; /*! * \brief Gets this instance's settings object. diff --git a/logic/ForgeInstaller.cpp b/logic/ForgeInstaller.cpp new file mode 100644 index 00000000..00ad8d19 --- /dev/null +++ b/logic/ForgeInstaller.cpp @@ -0,0 +1,125 @@ +#include "ForgeInstaller.h" +#include "OneSixVersion.h" +#include "OneSixLibrary.h" +#include +#include +#include +#include + +ForgeInstaller::ForgeInstaller(QString filename, QString universal_url) +{ + QSharedPointer newVersion; + m_universal_url = universal_url; + + QuaZip zip(filename); + if (!zip.open(QuaZip::mdUnzip)) + return; + + QuaZipFile file(&zip); + + // read the install profile + if (!zip.setCurrentFile("install_profile.json")) + return; + + QJsonParseError jsonError; + if (!file.open(QIODevice::ReadOnly)) + return; + QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError); + file.close(); + if (jsonError.error != QJsonParseError::NoError) + return; + + if (!jsonDoc.isObject()) + return; + + QJsonObject root = jsonDoc.object(); + + auto installVal = root.value("install"); + auto versionInfoVal = root.value("versionInfo"); + if (!installVal.isObject() || !versionInfoVal.isObject()) + return; + + // read the forge version info + { + newVersion = OneSixVersion::fromJson(versionInfoVal.toObject()); + if (!newVersion) + return; + } + + QJsonObject installObj = installVal.toObject(); + QString libraryName = installObj.value("path").toString(); + internalPath = installObj.value("filePath").toString(); + + // where do we put the library? decode the mojang path + OneSixLibrary lib(libraryName); + lib.finalize(); + finalPath = "libraries/" + lib.storagePath(); + if (!ensureFilePathExists(finalPath)) + return; + + if (!zip.setCurrentFile(internalPath)) + return; + if (!file.open(QIODevice::ReadOnly)) + return; + { + QByteArray data = file.readAll(); + // extract file + QSaveFile extraction(finalPath); + if (!extraction.open(QIODevice::WriteOnly)) + return; + if (extraction.write(data) != data.size()) + return; + if (!extraction.commit()) + return; + } + file.close(); + + m_forge_version = newVersion; + realVersionId = m_forge_version->id = installObj.value("minecraft").toString(); +} + +bool ForgeInstaller::apply(QSharedPointer to) +{ + if (!m_forge_version) + return false; + to->externalUpdateStart(); + int sliding_insert_window = 0; + { + // for each library in the version we are adding (except for the blacklisted) + QSet blacklist{"lwjgl", "lwjgl_util", "lwjgl-platform"}; + for (auto lib : m_forge_version->libraries) + { + QString libName = lib->name(); + // if this is the actual forge lib, set an absolute url for the download + if(libName.contains("minecraftforge")) + { + lib->setAbsoluteUrl(m_universal_url); + } + if (blacklist.contains(libName)) + continue; + + // find an entry that matches this one + bool found = false; + for (auto tolib : to->libraries) + { + if (tolib->name() != libName) + continue; + found = true; + // replace lib + tolib = lib; + break; + } + if (!found) + { + // add lib + to->libraries.insert(sliding_insert_window, lib); + sliding_insert_window++; + } + } + to->mainClass = m_forge_version->mainClass; + to->minecraftArguments = m_forge_version->minecraftArguments; + to->processArguments = m_forge_version->processArguments; + } + to->externalUpdateFinish(); + return to->toOriginalFile(); +} diff --git a/logic/ForgeInstaller.h b/logic/ForgeInstaller.h new file mode 100644 index 00000000..f4ceaaef --- /dev/null +++ b/logic/ForgeInstaller.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +class OneSixVersion; + +class ForgeInstaller +{ +public: + ForgeInstaller(QString filename, QString universal_url); + + bool apply(QSharedPointer to); + +private: + // the version, read from the installer + QSharedPointer m_forge_version; + QString internalPath; + QString finalPath; + QString realVersionId; + QString m_universal_url; +}; + + + + diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index 0f58e3e3..84d3d830 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -60,7 +60,7 @@ void LegacyUpdate::lwjglStart() m_reply = QSharedPointer (rep, &QObject::deleteLater); connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); - connect(worker, SIGNAL(finished(QNetworkReply*)), SLOT(lwjglFinished(QNetworkReply*))); + connect(worker.data(), SIGNAL(finished(QNetworkReply*)), SLOT(lwjglFinished(QNetworkReply*))); //connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); } @@ -77,7 +77,7 @@ void LegacyUpdate::lwjglFinished(QNetworkReply* reply) "\nSometimes you have to wait a bit if you download many LWJGL versions in a row. YMMV"); return; } - auto *worker = MMC->qnam(); + auto worker = MMC->qnam(); //Here i check if there is a cookie for me in the reply and extract it QList cookies = qvariant_cast>(reply->header(QNetworkRequest::SetCookieHeader)); if(cookies.count() != 0) diff --git a/logic/ModList.h b/logic/ModList.h index 5395e9ae..e99b6c82 100644 --- a/logic/ModList.h +++ b/logic/ModList.h @@ -112,3 +112,6 @@ protected: QString m_list_id; QList mods; }; + + + diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 8124b4a0..9262b155 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -2,7 +2,7 @@ #include "OneSixInstance_p.h" #include "OneSixUpdate.h" #include "MinecraftProcess.h" -#include "VersionFactory.h" +#include "OneSixVersion.h" #include #include @@ -10,8 +10,9 @@ #include #include -OneSixInstance::OneSixInstance ( const QString& rootDir, SettingsObject* setting_obj, QObject* parent ) -: BaseInstance ( new OneSixInstancePrivate(), rootDir, setting_obj, parent ) +OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj, + QObject *parent) + : BaseInstance(new OneSixInstancePrivate(), rootDir, setting_obj, parent) { I_D(OneSixInstance); d->m_settings->registerSetting(new Setting("IntendedVersion", "")); @@ -19,7 +20,7 @@ OneSixInstance::OneSixInstance ( const QString& rootDir, SettingsObject* setting reloadFullVersion(); } -BaseUpdate* OneSixInstance::doUpdate() +BaseUpdate *OneSixInstance::doUpdate() { return new OneSixUpdate(this); } @@ -34,10 +35,10 @@ QString replaceTokensIn(QString text, QMap with) int head = 0; while ((head = token_regexp.indexIn(text, head)) != -1) { - result.append(text.mid(tail, head-tail)); + result.append(text.mid(tail, head - tail)); QString key = token_regexp.cap(1); auto iter = with.find(key); - if(iter != with.end()) + if (iter != with.end()) { result.append(*iter); } @@ -48,26 +49,26 @@ QString replaceTokensIn(QString text, QMap with) return result; } -QStringList OneSixInstance::processMinecraftArgs( QString user, QString session ) +QStringList OneSixInstance::processMinecraftArgs(QString user, QString session) { I_D(OneSixInstance); auto version = d->version; QString args_pattern = version->minecraftArguments; - + QMap token_mapping; token_mapping["auth_username"] = user; token_mapping["auth_session"] = session; - //FIXME: user and player name are DIFFERENT! + // FIXME: user and player name are DIFFERENT! token_mapping["auth_player_name"] = user; - //FIXME: WTF is this. I just plugged in a random UUID here. + // FIXME: WTF is this. I just plugged in a random UUID here. token_mapping["auth_uuid"] = "7d4bacf0-fd62-11e2-b778-0800200c9a66"; // obviously fake. - + // this is for offline: /* map["auth_player_name"] = "Player"; map["auth_player_name"] = "00000000-0000-0000-0000-000000000000"; */ - + token_mapping["profile_name"] = name(); token_mapping["version_name"] = version->id; @@ -75,8 +76,8 @@ QStringList OneSixInstance::processMinecraftArgs( QString user, QString session token_mapping["game_directory"] = absRootDir; QString absAssetsDir = QDir("assets/").absolutePath(); token_mapping["game_assets"] = absAssetsDir; - - QStringList parts = args_pattern.split(' ',QString::SkipEmptyParts); + + QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts); for (int i = 0; i < parts.length(); i++) { parts[i] = replaceTokensIn(parts[i], token_mapping); @@ -84,27 +85,28 @@ QStringList OneSixInstance::processMinecraftArgs( QString user, QString session return parts; } -MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString session ) +MinecraftProcess *OneSixInstance::prepareForLaunch(QString user, QString session) { I_D(OneSixInstance); cleanupAfterRun(); auto version = d->version; - if(!version) + if (!version) return nullptr; auto libs_to_extract = version->getActiveNativeLibs(); QString natives_dir_raw = PathCombine(instanceRoot(), "natives/"); bool success = ensureFolderPathExists(natives_dir_raw); - if(!success) + if (!success) { // FIXME: handle errors return nullptr; } - - for(auto lib: libs_to_extract) + + for (auto lib : libs_to_extract) { QString path = "libraries/" + lib->storagePath(); qDebug() << "Will extract " << path.toLocal8Bit(); - if(JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes).isEmpty()) + if (JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes) + .isEmpty()) { return nullptr; } @@ -116,11 +118,11 @@ MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString sessi args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt()); args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt()); QDir natives_dir(natives_dir_raw); - args << QString("-Djava.library.path=%1").arg( natives_dir.absolutePath() ); + args << QString("-Djava.library.path=%1").arg(natives_dir.absolutePath()); QString classPath; { auto libs = version->getActiveNormalLibs(); - for (auto lib: libs) + for (auto lib : libs) { QFileInfo fi(QString("libraries/") + lib->storagePath()); classPath.append(fi.absoluteFilePath()); @@ -134,16 +136,16 @@ MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString sessi QFileInfo fi(targetstr); classPath.append(fi.absoluteFilePath()); } - if(classPath.size()) + if (classPath.size()) { args << "-cp"; args << classPath; } args << version->mainClass; args.append(processMinecraftArgs(user, session)); - + // create the process and set its parameters - MinecraftProcess * proc = new MinecraftProcess(this); + MinecraftProcess *proc = new MinecraftProcess(this); proc->setMinecraftArguments(args); proc->setMinecraftWorkdir(minecraftRoot()); return proc; @@ -156,10 +158,10 @@ void OneSixInstance::cleanupAfterRun() dir.removeRecursively(); } -QSharedPointer< ModList > OneSixInstance::loaderModList() +QSharedPointer OneSixInstance::loaderModList() { I_D(OneSixInstance); - if(!d->loader_mod_list) + if (!d->loader_mod_list) { d->loader_mod_list.reset(new ModList(loaderModsDir())); } @@ -168,10 +170,10 @@ QSharedPointer< ModList > OneSixInstance::loaderModList() return d->loader_mod_list; } -QSharedPointer< ModList > OneSixInstance::resourcePackList() +QSharedPointer OneSixInstance::resourcePackList() { I_D(OneSixInstance); - if(!d->resource_pack_list) + if (!d->resource_pack_list) { d->resource_pack_list.reset(new ModList(resourcePacksDir())); } @@ -180,13 +182,12 @@ QSharedPointer< ModList > OneSixInstance::resourcePackList() return d->resource_pack_list; } - -QDialog * OneSixInstance::createModEditDialog ( QWidget* parent ) +QDialog *OneSixInstance::createModEditDialog(QWidget *parent) { return new OneSixModEditDialog(this, parent); } -bool OneSixInstance::setIntendedVersionId ( QString version ) +bool OneSixInstance::setIntendedVersionId(QString version) { settings().set("IntendedVersion", version); setShouldUpdate(true); @@ -198,16 +199,16 @@ QString OneSixInstance::intendedVersionId() const return settings().get("IntendedVersion").toString(); } -void OneSixInstance::setShouldUpdate ( bool val ) +void OneSixInstance::setShouldUpdate(bool val) { - settings().set ( "ShouldUpdate", val ); + settings().set("ShouldUpdate", val); } bool OneSixInstance::shouldUpdate() const { I_D(OneSixInstance); - QVariant var = settings().get ( "ShouldUpdate" ); - if ( !var.isValid() || var.toBool() == false ) + QVariant var = settings().get("ShouldUpdate"); + if (!var.isValid() || var.toBool() == false) { return intendedVersionId() != currentVersionId(); } @@ -228,56 +229,51 @@ QString OneSixInstance::currentVersionId() const bool OneSixInstance::customizeVersion() { - if(!versionIsCustom()) + if (!versionIsCustom()) { auto pathCustom = PathCombine(instanceRoot(), "custom.json"); auto pathOrig = PathCombine(instanceRoot(), "version.json"); QFile::copy(pathOrig, pathCustom); return reloadFullVersion(); } - else return true; + else + return true; } bool OneSixInstance::revertCustomVersion() { - if(versionIsCustom()) + if (versionIsCustom()) { auto path = PathCombine(instanceRoot(), "custom.json"); QFile::remove(path); return reloadFullVersion(); } - else return true; + else + return true; } - bool OneSixInstance::reloadFullVersion() { I_D(OneSixInstance); - + QString verpath = PathCombine(instanceRoot(), "version.json"); { QString verpath_custom = PathCombine(instanceRoot(), "custom.json"); QFile versionfile(verpath_custom); - if(versionfile.exists()) + if (versionfile.exists()) verpath = verpath_custom; } - - QFile versionfile(verpath); - if(versionfile.exists() && versionfile.open(QIODevice::ReadOnly)) + + auto version = OneSixVersion::fromFile(verpath); + if (version) { - FullVersionFactory fvf; - auto version = fvf.parse(versionfile.readAll()); - versionfile.close(); - if(version) - { - d->version = version; - return true; - } - }; + d->version = version; + return true; + } return false; } -QSharedPointer< OneSixVersion > OneSixInstance::getFullVersion() +QSharedPointer OneSixInstance::getFullVersion() { I_D(OneSixInstance); return d->version; @@ -293,9 +289,9 @@ QString OneSixInstance::defaultCustomBaseJar() const return PathCombine(instanceRoot(), "custom.jar"); } -bool OneSixInstance::menuActionEnabled ( QString action_name ) const +bool OneSixInstance::menuActionEnabled(QString action_name) const { - if(action_name == "actionChangeInstLWJGLVersion") + if (action_name == "actionChangeInstLWJGLVersion") return false; return true; } @@ -303,7 +299,7 @@ bool OneSixInstance::menuActionEnabled ( QString action_name ) const QString OneSixInstance::getStatusbarDescription() { QString descr = "One Six : " + intendedVersionId(); - if(versionIsCustom()) + if (versionIsCustom()) { descr + " (custom)"; } diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp index a45a4aec..8da1fde7 100644 --- a/logic/OneSixLibrary.cpp +++ b/logic/OneSixLibrary.cpp @@ -1,18 +1,19 @@ #include "OneSixLibrary.h" #include "OneSixRule.h" #include "OpSys.h" +#include void OneSixLibrary::finalize() { - QStringList parts = m_name.split ( ':' ); + QStringList parts = m_name.split(':'); QString relative = parts[0]; - relative.replace ( '.','/' ); + relative.replace('.', '/'); relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2]; - - if ( !m_is_native ) + + if (!m_is_native) relative += ".jar"; else { - if ( m_native_suffixes.contains ( currentSystem ) ) + if (m_native_suffixes.contains(currentSystem)) { relative += "-" + m_native_suffixes[currentSystem] + ".jar"; } @@ -22,30 +23,30 @@ void OneSixLibrary::finalize() relative += ".jar"; } } - + m_decentname = parts[1]; m_decentversion = parts[2]; m_storage_path = relative; - m_download_path = m_base_url + relative; - - if ( m_rules.empty() ) + m_download_url = m_base_url + relative; + + if (m_rules.empty()) { m_is_active = true; } else { RuleAction result = Disallow; - for ( auto rule: m_rules ) + for (auto rule : m_rules) { - RuleAction temp = rule->apply ( this ); - if ( temp != Defer ) + RuleAction temp = rule->apply(this); + if (temp != Defer) result = temp; } - m_is_active = ( result == Allow ); + m_is_active = (result == Allow); } - if ( m_is_native ) + if (m_is_native) { - m_is_active = m_is_active && m_native_suffixes.contains ( currentSystem ); + m_is_active = m_is_active && m_native_suffixes.contains(currentSystem); m_decenttype = "Native"; } else @@ -54,11 +55,11 @@ void OneSixLibrary::finalize() } } -void OneSixLibrary::setName ( QString name ) +void OneSixLibrary::setName(QString name) { m_name = name; } -void OneSixLibrary::setBaseUrl ( QString base_url ) +void OneSixLibrary::setBaseUrl(QString base_url) { m_base_url = base_url; } @@ -66,12 +67,12 @@ void OneSixLibrary::setIsNative() { m_is_native = true; } -void OneSixLibrary::addNative ( OpSys os, QString suffix ) +void OneSixLibrary::addNative(OpSys os, QString suffix) { m_is_native = true; m_native_suffixes[os] = suffix; } -void OneSixLibrary::setRules ( QList< QSharedPointer< Rule > > rules ) +void OneSixLibrary::setRules(QList> rules) { m_rules = rules; } @@ -83,11 +84,66 @@ bool OneSixLibrary::isNative() { return m_is_native; } -QString OneSixLibrary::downloadPath() +QString OneSixLibrary::downloadUrl() { - return m_download_path; + if(m_absolute_url.size()) + return m_absolute_url; + return m_download_url; } QString OneSixLibrary::storagePath() { return m_storage_path; } + +void OneSixLibrary::setAbsoluteUrl(QString absolute_url) +{ + m_absolute_url = absolute_url; +} + +QString OneSixLibrary::absoluteUrl() +{ + return m_absolute_url; +} + +QJsonObject OneSixLibrary::toJson() +{ + QJsonObject libRoot; + libRoot.insert("name", m_name); + if(m_absolute_url.size()) + libRoot.insert("MMC-absulute_url", m_absolute_url); + if(m_base_url != "https://s3.amazonaws.com/Minecraft.Download/libraries/") + libRoot.insert("url", m_base_url); + if (isNative() && m_native_suffixes.size()) + { + QJsonObject nativeList; + auto iter = m_native_suffixes.begin(); + while (iter != m_native_suffixes.end()) + { + nativeList.insert(OpSys_toString(iter.key()), iter.value()); + iter++; + } + libRoot.insert("natives", nativeList); + } + if (isNative() && extract_excludes.size()) + { + QJsonArray excludes; + QJsonObject extract; + for (auto exclude : extract_excludes) + { + excludes.append(exclude); + } + extract.insert("exclude", excludes); + libRoot.insert("extract", extract); + } + if (m_rules.size()) + { + QJsonArray allRules; + for (auto &rule : m_rules) + { + QJsonObject ruleObj = rule->toJson(); + allRules.append(ruleObj); + } + libRoot.insert("rules", allRules); + } + return libRoot; +} diff --git a/logic/OneSixLibrary.h b/logic/OneSixLibrary.h index ac16d3d3..f3106483 100644 --- a/logic/OneSixLibrary.h +++ b/logic/OneSixLibrary.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "OpSys.h" class Rule; @@ -12,9 +13,13 @@ class OneSixLibrary private: // basic values used internally (so far) QString m_name; - QString m_base_url; + QString m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/"; QList > m_rules; - + + // custom values + /// absolute URL. takes precedence over m_download_path, if defined + QString m_absolute_url; + // derived values used for real things /// a decent name fit for display QString m_decentname; @@ -25,11 +30,11 @@ private: /// where to store the lib locally QString m_storage_path; /// where to download the lib from - QString m_download_path; + QString m_download_url; /// is this lib actually active on the current OS? - bool m_is_active; + bool m_is_active = false; /// is the library a native? - bool m_is_native; + bool m_is_native = false; /// native suffixes per OS QMap m_native_suffixes; public: @@ -39,12 +44,11 @@ public: /// Constructor OneSixLibrary(QString name) { - m_is_native = false; - m_is_active = false; m_name = name; - m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/"; } + QJsonObject toJson(); + /** * finalize the library, processing the input values into derived values and state * @@ -84,7 +88,11 @@ public: /// Returns true if the library is native bool isNative(); /// Get the URL to download the library from - QString downloadPath(); + QString downloadUrl(); /// Get the relative path where the library should be saved QString storagePath(); + + /// set an absolute URL for the library. This is an MMC extension. + void setAbsoluteUrl(QString absolute_url); + QString absoluteUrl(); }; diff --git a/logic/OneSixRule.cpp b/logic/OneSixRule.cpp index 85f7d434..545cd641 100644 --- a/logic/OneSixRule.cpp +++ b/logic/OneSixRule.cpp @@ -1,10 +1,72 @@ #include "OneSixRule.h" +#include +#include + +QList> rulesFromJsonV4(QJsonObject &objectWithRules) +{ + QList> rules; + auto rulesVal = objectWithRules.value("rules"); + if (!rulesVal.isArray()) + return rules; + + QJsonArray ruleList = rulesVal.toArray(); + for (auto ruleVal : ruleList) + { + QSharedPointer rule; + if (!ruleVal.isObject()) + continue; + auto ruleObj = ruleVal.toObject(); + auto actionVal = ruleObj.value("action"); + if (!actionVal.isString()) + continue; + auto action = RuleAction_fromString(actionVal.toString()); + if (action == Defer) + continue; + + auto osVal = ruleObj.value("os"); + if (!osVal.isObject()) + { + // add a new implicit action rule + rules.append(ImplicitRule::create(action)); + continue; + } + + auto osObj = osVal.toObject(); + auto osNameVal = osObj.value("name"); + if (!osNameVal.isString()) + continue; + OpSys requiredOs = OpSys_fromString(osNameVal.toString()); + QString versionRegex = osObj.value("version").toString(); + // add a new OS rule + rules.append(OsRule::create(action, requiredOs, versionRegex)); + } +} + +QJsonObject ImplicitRule::toJson() +{ + QJsonObject ruleObj; + ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); + return ruleObj; +} + +QJsonObject OsRule::toJson() +{ + QJsonObject ruleObj; + ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); + QJsonObject osObj; + { + osObj.insert("name", OpSys_toString(m_system)); + osObj.insert("version", m_version_regexp); + } + ruleObj.insert("os", osObj); + return ruleObj; +} RuleAction RuleAction_fromString(QString name) { - if(name == "allow") + if (name == "allow") return Allow; - if(name == "disallow") + if (name == "disallow") return Disallow; return Defer; } \ No newline at end of file diff --git a/logic/OneSixRule.h b/logic/OneSixRule.h index 465c963f..23d20ff4 100644 --- a/logic/OneSixRule.h +++ b/logic/OneSixRule.h @@ -1,8 +1,6 @@ #pragma once #include #include - -class OneSixLibrary; #include "OneSixLibrary.h" enum RuleAction @@ -13,6 +11,7 @@ enum RuleAction }; RuleAction RuleAction_fromString(QString); +QList> rulesFromJsonV4(QJsonObject &objectWithRules); class Rule { @@ -23,6 +22,7 @@ public: Rule(RuleAction result) :m_result(result) {} virtual ~Rule(){}; + virtual QJsonObject toJson() = 0; RuleAction apply(OneSixLibrary * parent) { if(applies(parent)) @@ -47,6 +47,7 @@ protected: OsRule(RuleAction result, OpSys system, QString version_regexp) : Rule(result), m_system(system), m_version_regexp(version_regexp) {} public: + virtual QJsonObject toJson(); static QSharedPointer create(RuleAction result, OpSys system, QString version_regexp) { return QSharedPointer (new OsRule(result, system, version_regexp)); @@ -63,6 +64,7 @@ protected: ImplicitRule(RuleAction result) : Rule(result) {} public: + virtual QJsonObject toJson(); static QSharedPointer create(RuleAction result) { return QSharedPointer (new ImplicitRule(result)); diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 298ad28a..d0af8b93 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software @@ -26,20 +26,20 @@ #include "BaseInstance.h" #include "lists/MinecraftVersionList.h" -#include "VersionFactory.h" #include "OneSixVersion.h" #include "OneSixLibrary.h" #include "OneSixInstance.h" #include "pathutils.h" - -OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent):BaseUpdate(inst, parent){} +OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) : BaseUpdate(inst, parent) +{ +} void OneSixUpdate::executeTask() { QString intendedVersion = m_inst->intendedVersionId(); - + // Make directories QDir mcDir(m_inst->minecraftRoot()); if (!mcDir.exists() && !mcDir.mkpath(".")) @@ -47,17 +47,18 @@ void OneSixUpdate::executeTask() emitFailed("Failed to create bin folder."); return; } - + // Get a pointer to the version object that corresponds to the instance's version. - targetVersion = MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast(); - if(targetVersion == nullptr) + targetVersion = + MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast(); + if (targetVersion == nullptr) { // don't do anything if it was invalid emitSucceeded(); return; } - - if(m_inst->shouldUpdate()) + + if (m_inst->shouldUpdate()) { versionFileStart(); } @@ -70,62 +71,65 @@ void OneSixUpdate::executeTask() void OneSixUpdate::versionFileStart() { setStatus("Getting the version files from Mojang."); - + QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; auto job = new DownloadJob("Version index"); job->add(QUrl(urlstr)); specificVersionDownloadJob.reset(job); - connect(specificVersionDownloadJob.data(), SIGNAL(succeeded()), SLOT(versionFileFinished())); + connect(specificVersionDownloadJob.data(), SIGNAL(succeeded()), + SLOT(versionFileFinished())); connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed())); - connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); + connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64, qint64)), + SIGNAL(progress(qint64, qint64))); specificVersionDownloadJob->start(); } void OneSixUpdate::versionFileFinished() { DownloadPtr DlJob = specificVersionDownloadJob->first(); - OneSixInstance * inst = (OneSixInstance *) m_inst; - + OneSixInstance *inst = (OneSixInstance *)m_inst; + QString version_id = targetVersion->descriptor(); QString inst_dir = m_inst->instanceRoot(); // save the version file in $instanceId/version.json { - QString version1 = PathCombine(inst_dir, "/version.json"); + QString version1 = PathCombine(inst_dir, "/version.json"); ensureFilePathExists(version1); // FIXME: detect errors here, download to a temp file, swap - QSaveFile vfile1 (version1); - if(!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly )) + QSaveFile vfile1(version1); + if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly)) { emitFailed("Can't open " + version1 + " for writing."); return; } auto data = DlJob.dynamicCast()->m_data; qint64 actual = 0; - if((actual = vfile1.write(data)) != data.size()) + if ((actual = vfile1.write(data)) != data.size()) { - emitFailed("Failed to write into " + version1 + ". Written " + actual + " out of " + data.size() + '.'); + emitFailed("Failed to write into " + version1 + ". Written " + actual + " out of " + + data.size() + '.'); return; } - if(!vfile1.commit()) + if (!vfile1.commit()) { emitFailed("Can't commit changes to " + version1); return; } } - + // the version is downloaded safely. update is 'done' at this point m_inst->setShouldUpdate(false); - + // delete any custom version inside the instance (it's no longer relevant, we did an update) - QString custom = PathCombine(inst_dir, "/custom.json"); + QString custom = PathCombine(inst_dir, "/custom.json"); QFile finfo(custom); - if(finfo.exists()) + if (finfo.exists()) { finfo.remove(); } inst->reloadFullVersion(); - + jarlibStart(); } @@ -136,42 +140,44 @@ void OneSixUpdate::versionFileFailed() void OneSixUpdate::jarlibStart() { - OneSixInstance * inst = (OneSixInstance *) m_inst; + OneSixInstance *inst = (OneSixInstance *)m_inst; bool successful = inst->reloadFullVersion(); - if(!successful) + if (!successful) { - emitFailed("Failed to load the version description file (version.json). It might be corrupted, missing or simply too new."); + emitFailed("Failed to load the version description file (version.json). It might be " + "corrupted, missing or simply too new."); return; } - + QSharedPointer version = inst->getFullVersion(); - + // download the right jar, save it in versions/$version/$version.jar QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); urlstr += version->id + "/" + version->id + ".jar"; - QString targetstr ("versions/"); + QString targetstr("versions/"); targetstr += version->id + "/" + version->id + ".jar"; - + auto job = new DownloadJob("Libraries for instance " + inst->name()); job->add(QUrl(urlstr), targetstr); jarlibDownloadJob.reset(job); - + auto libs = version->getActiveNativeLibs(); libs.append(version->getActiveNormalLibs()); - + auto metacache = MMC->metacache(); - for(auto lib: libs) + for (auto lib : libs) { - QString download_path = lib->downloadPath(); + QString download_path = lib->downloadUrl(); auto entry = metacache->resolveEntry("libraries", lib->storagePath()); - if(entry->stale) + if (entry->stale) { jarlibDownloadJob->add(download_path, entry); } } connect(jarlibDownloadJob.data(), SIGNAL(succeeded()), SLOT(jarlibFinished())); connect(jarlibDownloadJob.data(), SIGNAL(failed()), SLOT(jarlibFailed())); - connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); + connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64, qint64)), + SIGNAL(progress(qint64, qint64))); jarlibDownloadJob->start(); } @@ -185,4 +191,3 @@ void OneSixUpdate::jarlibFailed() { emitFailed("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE"); } - diff --git a/logic/OneSixVersion.cpp b/logic/OneSixVersion.cpp index dc1b5d6f..663d903a 100644 --- a/logic/OneSixVersion.cpp +++ b/logic/OneSixVersion.cpp @@ -1,10 +1,201 @@ #include "OneSixVersion.h" #include "OneSixLibrary.h" +#include "OneSixRule.h" -QList > OneSixVersion::getActiveNormalLibs() +QSharedPointer fromJsonV4(QJsonObject root, + QSharedPointer fullVersion) { - QList > output; - for ( auto lib: libraries ) + fullVersion->id = root.value("id").toString(); + + fullVersion->mainClass = root.value("mainClass").toString(); + auto procArgsValue = root.value("processArguments"); + if (procArgsValue.isString()) + { + fullVersion->processArguments = procArgsValue.toString(); + QString toCompare = fullVersion->processArguments.toLower(); + if (toCompare == "legacy") + { + fullVersion->minecraftArguments = " ${auth_player_name} ${auth_session}"; + } + else if (toCompare == "username_session") + { + fullVersion->minecraftArguments = + "--username ${auth_player_name} --session ${auth_session}"; + } + else if (toCompare == "username_session_version") + { + fullVersion->minecraftArguments = "--username ${auth_player_name} " + "--session ${auth_session} " + "--version ${profile_name}"; + } + } + + auto minecraftArgsValue = root.value("minecraftArguments"); + if (minecraftArgsValue.isString()) + { + fullVersion->minecraftArguments = minecraftArgsValue.toString(); + } + + auto minecraftTypeValue = root.value("type"); + if (minecraftTypeValue.isString()) + { + fullVersion->type = minecraftTypeValue.toString(); + } + + fullVersion->releaseTime = root.value("releaseTime").toString(); + fullVersion->time = root.value("time").toString(); + + // Iterate through the list, if it's a list. + auto librariesValue = root.value("libraries"); + if (!librariesValue.isArray()) + return fullVersion; + + QJsonArray libList = root.value("libraries").toArray(); + for (auto libVal : libList) + { + if (!libVal.isObject()) + { + continue; + } + + QJsonObject libObj = libVal.toObject(); + + // Library name + auto nameVal = libObj.value("name"); + if (!nameVal.isString()) + continue; + QSharedPointer library(new OneSixLibrary(nameVal.toString())); + + auto urlVal = libObj.value("url"); + if (urlVal.isString()) + { + library->setBaseUrl(urlVal.toString()); + } + auto urlAbsVal = libObj.value("MMC-absulute_url"); + if (urlAbsVal.isString()) + { + library->setAbsoluteUrl(urlAbsVal.toString()); + } + // Extract excludes (if any) + auto extractVal = libObj.value("extract"); + if (extractVal.isObject()) + { + QStringList excludes; + auto extractObj = extractVal.toObject(); + auto excludesVal = extractObj.value("exclude"); + if (excludesVal.isArray()) + { + auto excludesList = excludesVal.toArray(); + for (auto excludeVal : excludesList) + { + if (excludeVal.isString()) + excludes.append(excludeVal.toString()); + } + library->extract_excludes = excludes; + } + } + + auto nativesVal = libObj.value("natives"); + if (nativesVal.isObject()) + { + library->setIsNative(); + auto nativesObj = nativesVal.toObject(); + auto iter = nativesObj.begin(); + while (iter != nativesObj.end()) + { + auto osType = OpSys_fromString(iter.key()); + if (osType == Os_Other) + continue; + if (!iter.value().isString()) + continue; + library->addNative(osType, iter.value().toString()); + iter++; + } + } + library->setRules(rulesFromJsonV4(libObj)); + library->finalize(); + fullVersion->libraries.append(library); + } + return fullVersion; +} + +QSharedPointer OneSixVersion::fromJson(QJsonObject root) +{ + QSharedPointer readVersion(new OneSixVersion()); + int launcher_ver = readVersion->minimumLauncherVersion = + root.value("minimumLauncherVersion").toDouble(); + + // ADD MORE HERE :D + if (launcher_ver > 0 && launcher_ver <= 7) + return fromJsonV4(root, readVersion); + else + { + return QSharedPointer(); + } +} + +QSharedPointer OneSixVersion::fromFile(QString filepath) +{ + QFile file(filepath); + if (!file.open(QIODevice::ReadOnly)) + { + return QSharedPointer(); + } + + auto data = file.readAll(); + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + + if (jsonError.error != QJsonParseError::NoError) + { + return QSharedPointer(); + } + + if (!jsonDoc.isObject()) + { + return QSharedPointer(); + } + QJsonObject root = jsonDoc.object(); + auto version = fromJson(root); + version->original_file = filepath; + return version; +} + +bool OneSixVersion::toOriginalFile() +{ + if (original_file.isEmpty()) + return false; + QSaveFile file(original_file); + if (!file.open(QIODevice::WriteOnly)) + { + return false; + } + // serialize base attributes (those we care about anyway) + QJsonObject root; + root.insert("minecraftArguments", minecraftArguments); + root.insert("mainClass", mainClass); + root.insert("minimumLauncherVersion", minimumLauncherVersion); + root.insert("time", time); + root.insert("id", id); + root.insert("type", type); + // screw processArguments + root.insert("releaseTime", releaseTime); + QJsonArray libarray; + for(const auto & lib: libraries) + { + libarray.append(lib->toJson()); + } + if(libarray.count()) + root.insert("libraries", libarray); + QJsonDocument doc(root); + file.write(doc.toJson()); + return file.commit(); +} + +QList> OneSixVersion::getActiveNormalLibs() +{ + QList> output; + for (auto lib : libraries) { if (lib->isActive() && !lib->isNative()) { @@ -14,10 +205,10 @@ QList > OneSixVersion::getActiveNormalLibs() return output; } -QList > OneSixVersion::getActiveNativeLibs() +QList> OneSixVersion::getActiveNativeLibs() { - QList > output; - for ( auto lib: libraries ) + QList> output; + for (auto lib : libraries) { if (lib->isActive() && lib->isNative()) { @@ -27,41 +218,50 @@ QList > OneSixVersion::getActiveNativeLibs() return output; } +void OneSixVersion::externalUpdateStart() +{ + beginResetModel(); +} + +void OneSixVersion::externalUpdateFinish() +{ + endResetModel(); +} -QVariant OneSixVersion::data(const QModelIndex& index, int role) const +QVariant OneSixVersion::data(const QModelIndex &index, int role) const { - if(!index.isValid()) + if (!index.isValid()) return QVariant(); - + int row = index.row(); int column = index.column(); - - if(row < 0 || row >= libraries.size()) + + if (row < 0 || row >= libraries.size()) return QVariant(); - - if(role == Qt::DisplayRole) + + if (role == Qt::DisplayRole) { - switch(column) + switch (column) { - case 0: - return libraries[row]->name(); - case 1: - return libraries[row]->type(); - case 2: - return libraries[row]->version(); - default: - return QVariant(); + case 0: + return libraries[row]->name(); + case 1: + return libraries[row]->type(); + case 2: + return libraries[row]->version(); + default: + return QVariant(); } } return QVariant(); } -Qt::ItemFlags OneSixVersion::flags(const QModelIndex& index) const +Qt::ItemFlags OneSixVersion::flags(const QModelIndex &index) const { - if(!index.isValid()) + if (!index.isValid()) return Qt::NoItemFlags; int row = index.row(); - if(libraries[row]->isActive()) + if (libraries[row]->isActive()) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; } @@ -69,11 +269,10 @@ Qt::ItemFlags OneSixVersion::flags(const QModelIndex& index) const { return Qt::ItemNeverHasChildren; } - //return QAbstractListModel::flags(index); + // return QAbstractListModel::flags(index); } - -QVariant OneSixVersion::headerData ( int section, Qt::Orientation orientation, int role ) const +QVariant OneSixVersion::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole || orientation != Qt::Horizontal) return QVariant(); @@ -90,12 +289,12 @@ QVariant OneSixVersion::headerData ( int section, Qt::Orientation orientation, i } } -int OneSixVersion::rowCount(const QModelIndex& parent) const +int OneSixVersion::rowCount(const QModelIndex &parent) const { return libraries.size(); } -int OneSixVersion::columnCount(const QModelIndex& parent) const +int OneSixVersion::columnCount(const QModelIndex &parent) const { - return 3; + return 3; } diff --git a/logic/OneSixVersion.h b/logic/OneSixVersion.h index 6a6a5b4b..69268ecf 100644 --- a/logic/OneSixVersion.h +++ b/logic/OneSixVersion.h @@ -4,13 +4,33 @@ class OneSixLibrary; class OneSixVersion : public QAbstractListModel { + // Things required to implement the Qt list model public: - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const; - virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; - virtual int columnCount ( const QModelIndex& parent ) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &parent) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + // serialization/deserialization +public: + bool toOriginalFile(); + static QSharedPointer fromJson(QJsonObject root); + static QSharedPointer fromFile(QString filepath); + public: + QList> getActiveNormalLibs(); + QList> getActiveNativeLibs(); + // called when something starts/stops messing with the object + // FIXME: these are ugly in every possible way. + void externalUpdateStart(); + void externalUpdateFinish(); + + // data members +public: + /// file this was read from. blank, if none + QString original_file; /// the ID - determines which jar to use! ACTUALLY IMPORTANT! QString id; /// Last updated time - as a string @@ -23,26 +43,27 @@ public: * DEPRECATED: Old versions of the new vanilla launcher used this * ex: "username_session_version" */ - QString processArguments; + QString processArguments; /** * arguments that should be used for launching minecraft - * + * * ex: "--username ${auth_player_name} --session ${auth_session} * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}" */ QString minecraftArguments; /** - * the minimum launcher version required by this version ... current is 4 (at point of writing) + * the minimum launcher version required by this version ... current is 4 (at point of + * writing) */ - int minimumLauncherVersion; + int minimumLauncherVersion = 0xDEADBEEF; /** * The main class to load first */ QString mainClass; - + /// the list of libs - both active and inactive, native and java - QList > libraries; - + QList> libraries; + /* FIXME: add support for those rules here? Looks like a pile of quick hacks to me though. @@ -58,18 +79,11 @@ public: } } ], - "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!" + "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX + 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!" } */ // QList rules; - -public: - - OneSixVersion() - { - minimumLauncherVersion = 0xDEADBEEF; - } - - QList > getActiveNormalLibs(); - QList > getActiveNativeLibs(); + + }; diff --git a/logic/OpSys.cpp b/logic/OpSys.cpp index 559479fd..f101fd08 100644 --- a/logic/OpSys.cpp +++ b/logic/OpSys.cpp @@ -9,4 +9,15 @@ OpSys OpSys_fromString(QString name) if(name == "osx") return Os_OSX; return Os_Other; +} + +QString OpSys_toString(OpSys name) +{ + switch(name) + { + case Os_Linux: return "linux"; + case Os_OSX: return "osx"; + case Os_Windows: return "windows"; + default: return "other"; + } } \ No newline at end of file diff --git a/logic/OpSys.h b/logic/OpSys.h index c68c437a..aaa2eb65 100644 --- a/logic/OpSys.h +++ b/logic/OpSys.h @@ -9,6 +9,7 @@ enum OpSys }; OpSys OpSys_fromString(QString); +QString OpSys_toString(OpSys); #ifdef Q_OS_WIN32 #define currentSystem Os_Windows diff --git a/logic/VersionFactory.cpp b/logic/VersionFactory.cpp deleted file mode 100644 index 4fa5ad3f..00000000 --- a/logic/VersionFactory.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "VersionFactory.h" -#include "OneSixVersion.h" -#include "OneSixRule.h" - -// Library rules (if any) -QList > FullVersionFactory::parse4rules(QJsonObject & baseObj) -{ - QList > rules; - auto rulesVal = baseObj.value("rules"); - if(rulesVal.isArray()) - { - QJsonArray ruleList = rulesVal.toArray(); - for(auto ruleVal : ruleList) - { - QSharedPointer rule; - if(!ruleVal.isObject()) - continue; - auto ruleObj = ruleVal.toObject(); - auto actionVal = ruleObj.value("action"); - if(!actionVal.isString()) - continue; - auto action = RuleAction_fromString(actionVal.toString()); - if(action == Defer) - continue; - - auto osVal = ruleObj.value("os"); - if(!osVal.isObject()) - { - // add a new implicit action rule - rules.append(ImplicitRule::create(action)); - } - else - { - auto osObj = osVal.toObject(); - auto osNameVal = osObj.value("name"); - if(!osNameVal.isString()) - continue; - OpSys requiredOs = OpSys_fromString(osNameVal.toString()); - QString versionRegex = osObj.value("version").toString(); - // add a new OS rule - rules.append(OsRule::create(action, requiredOs, versionRegex)); - } - } - } - return rules; -} - - -QSharedPointer FullVersionFactory::parse4(QJsonObject root, QSharedPointer fullVersion) -{ - fullVersion->id = root.value("id").toString(); - - fullVersion->mainClass = root.value("mainClass").toString(); - auto procArgsValue = root.value("processArguments"); - if(procArgsValue.isString()) - { - fullVersion->processArguments = procArgsValue.toString(); - QString toCompare = fullVersion->processArguments.toLower(); - if(toCompare == "legacy") - { - fullVersion->minecraftArguments = " ${auth_player_name} ${auth_session}"; - } - else if(toCompare == "username_session") - { - fullVersion->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}"; - } - else if(toCompare == "username_session_version") - { - fullVersion->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}"; - } - } - - auto minecraftArgsValue = root.value("minecraftArguments"); - if(minecraftArgsValue.isString()) - { - fullVersion->minecraftArguments = minecraftArgsValue.toString(); - } - - auto minecraftTypeValue = root.value("type"); - if(minecraftTypeValue.isString()) - { - fullVersion->type = minecraftTypeValue.toString(); - } - - fullVersion->releaseTime = root.value("releaseTime").toString(); - fullVersion->time = root.value("time").toString(); - - // Iterate through the list, if it's a list. - auto librariesValue = root.value("libraries"); - if(!librariesValue.isArray()) - return fullVersion; - - QJsonArray libList = root.value("libraries").toArray(); - for (auto libVal : libList) - { - if (!libVal.isObject()) - { - continue; - } - - QJsonObject libObj = libVal.toObject(); - - // Library name - auto nameVal = libObj.value("name"); - if(!nameVal.isString()) - continue; - QSharedPointer library(new OneSixLibrary(nameVal.toString())); - - auto urlVal = libObj.value("url"); - if(urlVal.isString()) - { - library->setBaseUrl(urlVal.toString()); - } - - // Extract excludes (if any) - auto extractVal = libObj.value("extract"); - if(extractVal.isObject()) - { - QStringList excludes; - auto extractObj = extractVal.toObject(); - auto excludesVal = extractObj.value("exclude"); - if(!excludesVal.isArray()) - goto SKIP_EXTRACTS; - auto excludesList = excludesVal.toArray(); - for(auto excludeVal : excludesList) - { - if(excludeVal.isString()) - excludes.append(excludeVal.toString()); - } - library->extract_excludes = excludes; - } - SKIP_EXTRACTS: - - auto nativesVal = libObj.value("natives"); - if(nativesVal.isObject()) - { - library->setIsNative(); - auto nativesObj = nativesVal.toObject(); - auto iter = nativesObj.begin(); - while(iter != nativesObj.end()) - { - auto osType = OpSys_fromString(iter.key()); - if(osType == Os_Other) - continue; - if(!iter.value().isString()) - continue; - library->addNative(osType, iter.value().toString()); - iter++; - } - } - library->setRules(parse4rules(libObj)); - library->finalize(); - fullVersion->libraries.append(library); - } - return fullVersion; -} - -QSharedPointer FullVersionFactory::parse(QByteArray data) -{ - QSharedPointer readVersion(new OneSixVersion()); - - QJsonParseError jsonError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); - - if (jsonError.error != QJsonParseError::NoError) - { - error_string = QString( "Error reading version file :") + " " + jsonError.errorString(); - m_error = FullVersionFactory::ParseError; - return QSharedPointer(); - } - - if(!jsonDoc.isObject()) - { - error_string = "Error reading version file."; - m_error = FullVersionFactory::ParseError; - return QSharedPointer(); - } - QJsonObject root = jsonDoc.object(); - - int launcher_ver = readVersion->minimumLauncherVersion = root.value("minimumLauncherVersion").toDouble(); - // ADD MORE HERE :D - if(launcher_ver > 0 && launcher_ver <= 7) - return parse4(root, readVersion); - else - { - error_string = "Version file was for an unrecognized launcher version. RIP"; - m_error = FullVersionFactory::UnsupportedVersion; - return QSharedPointer(); - } -} - - -FullVersionFactory::FullVersionFactory() -{ - m_error = FullVersionFactory::AllOK; -} diff --git a/logic/VersionFactory.h b/logic/VersionFactory.h deleted file mode 100644 index 0c0ee2d4..00000000 --- a/logic/VersionFactory.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include - -struct OneSixVersion; -class Rule; - -class FullVersionFactory -{ -public: - enum Error - { - AllOK, // all parsed OK - ParseError, // the file was corrupted somehow - UnsupportedVersion // the file was meant for a launcher version we don't support (yet) - } m_error; - QString error_string; - -public: - FullVersionFactory(); - QSharedPointer parse(QByteArray data); -private: - QSharedPointer parse4(QJsonObject root, QSharedPointer product); - QList > parse4rules(QJsonObject & baseObj); -}; \ No newline at end of file diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp index 492849ee..9205e70f 100644 --- a/logic/lists/ForgeVersionList.cpp +++ b/logic/lists/ForgeVersionList.cpp @@ -260,8 +260,10 @@ void ForgeListLoadTask::list_downloaded() fVersion->installer_url = installer_url; fVersion->jobbuildver = jobbuildver; fVersion->mcver = mcver; - fVersion->filename = filename; - fVersion->filename = installer_filename; + if(installer_filename.isEmpty()) + fVersion->filename = filename; + else + fVersion->filename = installer_filename; fVersion->m_buildnr = build_nr; tempList.append(fVersion); } @@ -271,3 +273,8 @@ void ForgeListLoadTask::list_downloaded() emitSucceeded(); return; } + + + + + diff --git a/logic/lists/ForgeVersionList.h b/logic/lists/ForgeVersionList.h index ca6b27bc..613de8a6 100644 --- a/logic/lists/ForgeVersionList.h +++ b/logic/lists/ForgeVersionList.h @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software @@ -33,19 +33,22 @@ struct ForgeVersion : public BaseVersion virtual QString descriptor() { return filename; - }; + } + ; virtual QString name() { return "Forge " + jobbuildver; - }; + } + ; virtual QString typeString() const { - if(installer_url.isEmpty()) + if (installer_url.isEmpty()) return "Universal"; else return "Installer"; - }; - + } + ; + int m_buildnr = 0; QString universal_url; QString changelog_url; @@ -60,42 +63,45 @@ class ForgeVersionList : public BaseVersionList Q_OBJECT public: friend class ForgeListLoadTask; - + explicit ForgeVersionList(QObject *parent = 0); - + virtual Task *getLoadTask(); virtual bool isLoaded(); virtual const BaseVersionPtr at(int i) const; virtual int count() const; virtual void sort(); - + virtual BaseVersionPtr getLatestStable() const; - - virtual QVariant data(const QModelIndex& index, int role) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; - virtual int columnCount(const QModelIndex& parent) const; - + + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role) const; + virtual int columnCount(const QModelIndex &parent) const; + protected: QList m_vlist; - + bool m_loaded; - -protected slots: - virtual void updateListData(QList versions); + +protected +slots: + virtual void updateListData(QList versions); }; class ForgeListLoadTask : public Task { Q_OBJECT - + public: explicit ForgeListLoadTask(ForgeVersionList *vlist); - + virtual void executeTask(); - -protected slots: + +protected +slots: void list_downloaded(); - + protected: DownloadJobPtr listJob; ForgeVersionList *m_list; diff --git a/logic/tasks/LoginTask.cpp b/logic/tasks/LoginTask.cpp index 859827bc..222af618 100644 --- a/logic/tasks/LoginTask.cpp +++ b/logic/tasks/LoginTask.cpp @@ -30,7 +30,7 @@ void LoginTask::executeTask() { setStatus(tr("Logging in...")); auto worker = MMC->qnam(); - connect(worker, SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetReply(QNetworkReply*))); + connect(worker.data(), SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetReply(QNetworkReply*))); QUrl loginURL("https://login.minecraft.net/"); QNetworkRequest netRequest(loginURL); -- cgit v1.2.3