summaryrefslogtreecommitdiffstats
path: root/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-09-22 04:21:36 +0200
committerPetr Mrázek <peterix@gmail.com>2013-09-22 04:21:36 +0200
commitceca6959d2a7f258d62ac4f589095b65084706c3 (patch)
tree8ce02eb4713bf8e770e02e97c99ad45f492cc688 /logic
parentc2c7293083de8e8d40190992ccd6a65b613a4d06 (diff)
downloadMultiMC-ceca6959d2a7f258d62ac4f589095b65084706c3.tar
MultiMC-ceca6959d2a7f258d62ac4f589095b65084706c3.tar.gz
MultiMC-ceca6959d2a7f258d62ac4f589095b65084706c3.tar.lz
MultiMC-ceca6959d2a7f258d62ac4f589095b65084706c3.tar.xz
MultiMC-ceca6959d2a7f258d62ac4f589095b65084706c3.zip
Working 1.6 modding (currently only forge)
Diffstat (limited to 'logic')
-rw-r--r--logic/BaseInstance.cpp2
-rw-r--r--logic/BaseInstance.h2
-rw-r--r--logic/ForgeInstaller.cpp125
-rw-r--r--logic/ForgeInstaller.h25
-rw-r--r--logic/LegacyUpdate.cpp4
-rw-r--r--logic/ModList.h3
-rw-r--r--logic/OneSixInstance.cpp114
-rw-r--r--logic/OneSixLibrary.cpp98
-rw-r--r--logic/OneSixLibrary.h26
-rw-r--r--logic/OneSixRule.cpp66
-rw-r--r--logic/OneSixRule.h6
-rw-r--r--logic/OneSixUpdate.cpp85
-rw-r--r--logic/OneSixVersion.cpp261
-rw-r--r--logic/OneSixVersion.h60
-rw-r--r--logic/OpSys.cpp11
-rw-r--r--logic/OpSys.h1
-rw-r--r--logic/VersionFactory.cpp196
-rw-r--r--logic/VersionFactory.h24
-rw-r--r--logic/lists/ForgeVersionList.cpp11
-rw-r--r--logic/lists/ForgeVersionList.h52
-rw-r--r--logic/tasks/LoginTask.cpp2
21 files changed, 737 insertions, 437 deletions
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<BaseVersionList> 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<BaseVersionList> 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 <quazip.h>
+#include <quazipfile.h>
+#include <pathutils.h>
+#include <QStringList>
+
+ForgeInstaller::ForgeInstaller(QString filename, QString universal_url)
+{
+ QSharedPointer<OneSixVersion> 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<OneSixVersion> 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<QString> 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 <QString>
+#include <QSharedPointer>
+
+class OneSixVersion;
+
+class ForgeInstaller
+{
+public:
+ ForgeInstaller(QString filename, QString universal_url);
+
+ bool apply(QSharedPointer<OneSixVersion> to);
+
+private:
+ // the version, read from the installer
+ QSharedPointer<OneSixVersion> 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<QNetworkReply> (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<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(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<Mod> 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 <setting.h>
#include <pathutils.h>
@@ -10,8 +10,9 @@
#include <JlCompress.h>
#include <gui/OneSixModEditDialog.h>
-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<QString, QString> 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<QString, QString> 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<QString, QString> 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<ModList> 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<ModList> 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<OneSixVersion> 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 <QJsonArray>
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<QSharedPointer<Rule>> 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 <QStringList>
#include <QMap>
#include <QSharedPointer>
+#include <QJsonObject>
#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<QSharedPointer<Rule> > 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<OpSys, QString> 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 <QJsonObject>
+#include <QJsonArray>
+
+QList<QSharedPointer<Rule>> rulesFromJsonV4(QJsonObject &objectWithRules)
+{
+ QList<QSharedPointer<Rule>> rules;
+ auto rulesVal = objectWithRules.value("rules");
+ if (!rulesVal.isArray())
+ return rules;
+
+ QJsonArray ruleList = rulesVal.toArray();
+ for (auto ruleVal : ruleList)
+ {
+ QSharedPointer<Rule> 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 <QString>
#include <QSharedPointer>
-
-class OneSixLibrary;
#include "OneSixLibrary.h"
enum RuleAction
@@ -13,6 +11,7 @@ enum RuleAction
};
RuleAction RuleAction_fromString(QString);
+QList<QSharedPointer<Rule>> 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<OsRule> create(RuleAction result, OpSys system, QString version_regexp)
{
return QSharedPointer<OsRule> (new OsRule(result, system, version_regexp));
@@ -63,6 +64,7 @@ protected:
ImplicitRule(RuleAction result)
: Rule(result) {}
public:
+ virtual QJsonObject toJson();
static QSharedPointer<ImplicitRule> create(RuleAction result)
{
return QSharedPointer<ImplicitRule> (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<MinecraftVersion>();
- if(targetVersion == nullptr)
+ targetVersion =
+ MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast<MinecraftVersion>();
+ 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<ByteArrayDownload>()->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<OneSixVersion> 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<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNormalLibs()
+QSharedPointer<OneSixVersion> fromJsonV4(QJsonObject root,
+ QSharedPointer<OneSixVersion> fullVersion)
{
- QList<QSharedPointer<OneSixLibrary> > 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<OneSixLibrary> 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> OneSixVersion::fromJson(QJsonObject root)
+{
+ QSharedPointer<OneSixVersion> 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<OneSixVersion>();
+ }
+}
+
+QSharedPointer<OneSixVersion> OneSixVersion::fromFile(QString filepath)
+{
+ QFile file(filepath);
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ return QSharedPointer<OneSixVersion>();
+ }
+
+ auto data = file.readAll();
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ return QSharedPointer<OneSixVersion>();
+ }
+
+ if (!jsonDoc.isObject())
+ {
+ return QSharedPointer<OneSixVersion>();
+ }
+ 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<QSharedPointer<OneSixLibrary>> OneSixVersion::getActiveNormalLibs()
+{
+ QList<QSharedPointer<OneSixLibrary>> output;
+ for (auto lib : libraries)
{
if (lib->isActive() && !lib->isNative())
{
@@ -14,10 +205,10 @@ QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNormalLibs()
return output;
}
-QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNativeLibs()
+QList<QSharedPointer<OneSixLibrary>> OneSixVersion::getActiveNativeLibs()
{
- QList<QSharedPointer<OneSixLibrary> > output;
- for ( auto lib: libraries )
+ QList<QSharedPointer<OneSixLibrary>> output;
+ for (auto lib : libraries)
{
if (lib->isActive() && lib->isNative())
{
@@ -27,41 +218,50 @@ QList<QSharedPointer<OneSixLibrary> > 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<OneSixVersion> fromJson(QJsonObject root);
+ static QSharedPointer<OneSixVersion> fromFile(QString filepath);
+
public:
+ QList<QSharedPointer<OneSixLibrary>> getActiveNormalLibs();
+ QList<QSharedPointer<OneSixLibrary>> 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<QSharedPointer<OneSixLibrary> > libraries;
-
+ QList<QSharedPointer<OneSixLibrary>> 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<Rule> rules;
-
-public:
-
- OneSixVersion()
- {
- minimumLauncherVersion = 0xDEADBEEF;
- }
-
- QList<QSharedPointer<OneSixLibrary> > getActiveNormalLibs();
- QList<QSharedPointer<OneSixLibrary> > 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<QSharedPointer<Rule> > FullVersionFactory::parse4rules(QJsonObject & baseObj)
-{
- QList<QSharedPointer<Rule> > rules;
- auto rulesVal = baseObj.value("rules");
- if(rulesVal.isArray())
- {
- QJsonArray ruleList = rulesVal.toArray();
- for(auto ruleVal : ruleList)
- {
- QSharedPointer<Rule> 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<OneSixVersion> FullVersionFactory::parse4(QJsonObject root, QSharedPointer<OneSixVersion> 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<OneSixLibrary> 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<OneSixVersion> FullVersionFactory::parse(QByteArray data)
-{
- QSharedPointer<OneSixVersion> 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<OneSixVersion>();
- }
-
- if(!jsonDoc.isObject())
- {
- error_string = "Error reading version file.";
- m_error = FullVersionFactory::ParseError;
- return QSharedPointer<OneSixVersion>();
- }
- 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<OneSixVersion>();
- }
-}
-
-
-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 <QtCore>
-
-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<OneSixVersion> parse(QByteArray data);
-private:
- QSharedPointer<OneSixVersion> parse4(QJsonObject root, QSharedPointer<OneSixVersion> product);
- QList<QSharedPointer<Rule> > 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<BaseVersionPtr> m_vlist;
-
+
bool m_loaded;
-
-protected slots:
- virtual void updateListData(QList<BaseVersionPtr > versions);
+
+protected
+slots:
+ virtual void updateListData(QList<BaseVersionPtr> 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);