summaryrefslogtreecommitdiffstats
path: root/backend
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-08-05 03:29:50 +0200
committerPetr Mrázek <peterix@gmail.com>2013-08-05 03:29:50 +0200
commit183a7351456940d01f14a49112ddeb68ffc4693a (patch)
tree579aeb0b8670e634de4f083e54b3c826bf548ec9 /backend
parent005a010ee6a67191ec24583780310fcf217ff30c (diff)
downloadMultiMC-183a7351456940d01f14a49112ddeb68ffc4693a.tar
MultiMC-183a7351456940d01f14a49112ddeb68ffc4693a.tar.gz
MultiMC-183a7351456940d01f14a49112ddeb68ffc4693a.tar.lz
MultiMC-183a7351456940d01f14a49112ddeb68ffc4693a.tar.xz
MultiMC-183a7351456940d01f14a49112ddeb68ffc4693a.zip
Runnable 1.6 instances!
Diffstat (limited to 'backend')
-rw-r--r--backend/BaseInstance.h19
-rw-r--r--backend/CMakeLists.txt2
-rw-r--r--backend/LegacyInstance.cpp40
-rw-r--r--backend/LegacyInstance.h33
-rw-r--r--backend/MinecraftProcess.cpp1
-rw-r--r--backend/OneSixInstance.cpp182
-rw-r--r--backend/OneSixInstance.h18
-rw-r--r--backend/OneSixInstance_p.h5
-rw-r--r--backend/OneSixUpdate.cpp111
-rw-r--r--backend/OneSixUpdate.h5
-rw-r--r--backend/OneSixVersion.cpp45
-rw-r--r--backend/OneSixVersion.h81
-rw-r--r--backend/lists/MinecraftVersionList.cpp28
-rw-r--r--backend/tasks/LoginTask.cpp12
-rw-r--r--backend/tasks/LoginTask.h6
-rw-r--r--backend/tasks/Task.cpp16
-rw-r--r--backend/tasks/Task.h10
17 files changed, 422 insertions, 192 deletions
diff --git a/backend/BaseInstance.h b/backend/BaseInstance.h
index eb13b92b..7454c17e 100644
--- a/backend/BaseInstance.h
+++ b/backend/BaseInstance.h
@@ -69,8 +69,23 @@ public:
QString group() const;
void setGroup(QString val);
+ virtual QString intendedVersionId() const = 0;
virtual bool setIntendedVersionId(QString version) = 0;
- virtual QString intendedVersionId() = 0;
+
+ /*!
+ * The instance's current version.
+ * This value represents the instance's current version. If this value is
+ * different from the intendedVersion, the instance should be updated.
+ * \warning Don't change this value unless you know what you're doing.
+ */
+ virtual QString currentVersionId() const = 0;
+ //virtual void setCurrentVersionId(QString val) = 0;
+
+ /*!
+ * Whether or not Minecraft should be downloaded when the instance is launched.
+ */
+ virtual bool shouldUpdate() const = 0;
+ virtual void setShouldUpdate(bool val) = 0;
/**
* Gets the time that the instance was last launched.
@@ -107,6 +122,8 @@ public:
/// returns a valid minecraft process, ready for launch
virtual MinecraftProcess* prepareForLaunch(QString user, QString session) = 0;
+ /// do any necessary cleanups after the instance finishes. also runs before 'prepareForLaunch'
+ virtual void cleanupAfterRun() = 0;
signals:
/*!
* \brief Signal emitted when properties relevant to the instance view change
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index 309dde97..4fbe7bed 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -91,6 +91,6 @@ add_definitions(-DLIBMULTIMC_LIBRARY)
add_library(backend SHARED ${LIBINST_SOURCES} ${LIBINST_HEADERS})
qt5_use_modules(backend Core Network Xml)
-target_link_libraries(backend libUtil libSettings)
+target_link_libraries(backend libUtil libSettings quazip)
diff --git a/backend/LegacyInstance.cpp b/backend/LegacyInstance.cpp
index aace2a22..dc6cf0db 100644
--- a/backend/LegacyInstance.cpp
+++ b/backend/LegacyInstance.cpp
@@ -16,7 +16,7 @@ LegacyInstance::LegacyInstance(const QString& rootDir, SettingsObject* settings,
settings->registerSetting(new Setting("NeedsRebuild", true));
settings->registerSetting(new Setting("ShouldUpdate", false));
settings->registerSetting(new Setting("JarVersion", "Unknown"));
- settings->registerSetting(new Setting("LwjglVersion", "2.9.0"));
+ settings->registerSetting(new Setting("LwjglVersion", "Mojang"));
settings->registerSetting(new Setting("IntendedJarVersion", ""));
}
@@ -93,6 +93,11 @@ MinecraftProcess* LegacyInstance::prepareForLaunch(QString user, QString session
return proc;
}
+void LegacyInstance::cleanupAfterRun()
+{
+ //FIXME: delete the launcher and icons and whatnot.
+}
+
QString LegacyInstance::instModsDir() const
{
@@ -152,7 +157,7 @@ void LegacyInstance::updateCurrentVersion(bool keepCurrent)
if(!jar.exists())
{
setLastCurrentVersionUpdate(0);
- setCurrentVersion("Unknown");
+ setCurrentVersionId("Unknown");
return;
}
@@ -163,7 +168,7 @@ void LegacyInstance::updateCurrentVersion(bool keepCurrent)
{
// TODO: Implement GetMinecraftJarVersion function.
QString newVersion = "Unknown";//javautils::GetMinecraftJarVersion(jar.absoluteFilePath());
- setCurrentVersion(newVersion);
+ setCurrentVersionId(newVersion);
}
}
qint64 LegacyInstance::lastCurrentVersionUpdate() const
@@ -186,16 +191,18 @@ void LegacyInstance::setShouldRebuild ( bool val )
I_D(LegacyInstance);
d->m_settings->set ( "NeedsRebuild", val );
}
-QString LegacyInstance::currentVersion() const
+QString LegacyInstance::currentVersionId() const
{
I_D(LegacyInstance);
return d->m_settings->get ( "JarVersion" ).toString();
}
-void LegacyInstance::setCurrentVersion ( QString val )
+
+void LegacyInstance::setCurrentVersionId ( QString val )
{
I_D(LegacyInstance);
d->m_settings->set ( "JarVersion", val );
}
+
QString LegacyInstance::lwjglVersion() const
{
I_D(LegacyInstance);
@@ -206,36 +213,17 @@ void LegacyInstance::setLWJGLVersion ( QString val )
I_D(LegacyInstance);
d->m_settings->set ( "LwjglVersion", val );
}
-QString LegacyInstance::intendedVersionId()
+QString LegacyInstance::intendedVersionId() const
{
I_D(LegacyInstance);
return d->m_settings->get ( "IntendedJarVersion" ).toString();
}
bool LegacyInstance::setIntendedVersionId ( QString version )
{
- /*
- I_D(LegacyInstance);
- d->m_settings->set ( "IntendedJarVersion", val );
- */
return false;
}
bool LegacyInstance::shouldUpdate() const
{
- /*
- I_D(LegacyInstance);
- QVariant var = d->m_settings->get ( "ShouldUpdate" );
- if ( !var.isValid() || var.toBool() == false )
- {
- return intendedVersionId() != currentVersion();
- }
- return true;
- */
return false;
}
-void LegacyInstance::setShouldUpdate ( bool val )
-{
- /*
- I_D(LegacyInstance);
- d->m_settings->set ( "ShouldUpdate", val );
- */
-}
+void LegacyInstance::setShouldUpdate ( bool val ) {}
diff --git a/backend/LegacyInstance.h b/backend/LegacyInstance.h
index dcc97448..e4ab6f29 100644
--- a/backend/LegacyInstance.h
+++ b/backend/LegacyInstance.h
@@ -56,7 +56,6 @@ public:
qint64 lastCurrentVersionUpdate() const;
void setLastCurrentVersionUpdate(qint64 val);
-
/*!
* Whether or not the instance's minecraft.jar needs to be rebuilt.
* If this is true, when the instance launches, its jar mods will be
@@ -65,39 +64,21 @@ public:
bool shouldRebuild() const;
void setShouldRebuild(bool val);
+ virtual QString currentVersionId() const;
+ virtual void setCurrentVersionId(QString val);
- /*!
- * The instance's current version.
- * This value represents the instance's current version. If this value is
- * different from the intendedVersion, the instance should be updated.
- * \warning Don't change this value unless you know what you're doing.
- */
- QString currentVersion() const;
- void setCurrentVersion(QString val);
-
//! The version of LWJGL that this instance uses.
QString lwjglVersion() const;
+ /// st the version of LWJGL libs this instance will use
void setLWJGLVersion(QString val);
- /*!
- * The version that the user has set for this instance to use.
- * If this is not the same as currentVersion, the instance's game updater
- * will be run on launch.
- */
- virtual QString intendedVersionId();
+ virtual QString intendedVersionId() const;
virtual bool setIntendedVersionId ( QString version );
- /*!
- * Whether or not Minecraft should be downloaded when the instance is launched.
- * This returns true if shouldForceUpdate game is true or if the intended and
- * current versions don't match.
- */
- bool shouldUpdate() const;
- void setShouldUpdate(bool val);
-
- /// return a valid GameUpdateTask if an update is needed, return NULL otherwise
+ virtual bool shouldUpdate() const;
+ virtual void setShouldUpdate(bool val);
virtual OneSixUpdate* doUpdate();
- /// prepare the instance for launch and return a constructed MinecraftProcess instance
virtual MinecraftProcess* prepareForLaunch( QString user, QString session );
+ virtual void cleanupAfterRun();
}; \ No newline at end of file
diff --git a/backend/MinecraftProcess.cpp b/backend/MinecraftProcess.cpp
index e6ea0034..d4d1da3c 100644
--- a/backend/MinecraftProcess.cpp
+++ b/backend/MinecraftProcess.cpp
@@ -134,6 +134,7 @@ void MinecraftProcess::finish(int code, ExitStatus status)
//TODO: error handling
}
}
+ m_instance->cleanupAfterRun();
emit ended();
}
diff --git a/backend/OneSixInstance.cpp b/backend/OneSixInstance.cpp
index e64f9b03..6df2b471 100644
--- a/backend/OneSixInstance.cpp
+++ b/backend/OneSixInstance.cpp
@@ -2,13 +2,20 @@
#include "OneSixInstance_p.h"
#include "OneSixUpdate.h"
#include "MinecraftProcess.h"
+#include "VersionFactory.h"
+
#include <setting.h>
+#include <pathutils.h>
+#include <cmdutils.h>
+#include <JlCompress.h>
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", ""));
+ d->m_settings->registerSetting(new Setting("ShouldUpdate", false));
+ reloadFullVersion();
}
OneSixUpdate* OneSixInstance::doUpdate()
@@ -16,17 +23,188 @@ OneSixUpdate* OneSixInstance::doUpdate()
return new OneSixUpdate(this);
}
+QString replaceTokensIn(QString text, QMap<QString, QString> with)
+{
+ QString result;
+ QRegExp token_regexp("\\$\\{(.+)\\}");
+ token_regexp.setMinimal(true);
+ QStringList list;
+ int tail = 0;
+ int head = 0;
+ while ((head = token_regexp.indexIn(text, head)) != -1)
+ {
+ result.append(text.mid(tail, head-tail));
+ QString key = token_regexp.cap(1);
+ auto iter = with.find(key);
+ if(iter != with.end())
+ {
+ result.append(*iter);
+ }
+ head += token_regexp.matchedLength();
+ tail = head;
+ }
+ result.append(text.mid(tail));
+ return result;
+}
+
+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!
+ token_mapping["auth_player_name"] = user;
+ //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;
+
+ QString absRootDir = QDir(rootDir()).absolutePath();
+ token_mapping["game_directory"] = absRootDir;
+ QString absAssetsDir = QDir("assets/").absolutePath();
+ token_mapping["game_assets"] = absAssetsDir;
+
+ QStringList parts = args_pattern.split(' ',QString::SkipEmptyParts);
+ for (int i = 0; i < parts.length(); i++)
+ {
+ parts[i] = replaceTokensIn(parts[i], token_mapping);
+ }
+ return parts;
+}
+
MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString session )
{
- return nullptr;
+ I_D(OneSixInstance);
+ cleanupAfterRun();
+ auto version = d->version;
+ if(!version)
+ return nullptr;
+ auto libs_to_extract = version->getActiveNativeLibs();
+ QString natives_dir_raw = PathCombine(rootDir(), "natives/");
+ bool success = ensurePathExists(natives_dir_raw);
+ if(!success)
+ {
+ // FIXME: handle errors
+ return nullptr;
+ }
+
+ 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())
+ {
+ return nullptr;
+ }
+ }
+
+ QStringList args;
+ args.append(Util::Commandline::splitArgs(settings().get("JvmArgs").toString()));
+ args << QString("-Xms%1m").arg(settings().get("MinMemAlloc").toInt());
+ args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt());
+ QDir natives_dir(natives_dir_raw);
+ args << QString("-Djava.library.path=%1").arg( natives_dir.absolutePath() );
+ QString classPath;
+ {
+ auto libs = version->getActiveNormalLibs();
+ for (auto lib: libs)
+ {
+ QFileInfo fi(QString("libraries/") + lib->storagePath());
+ classPath.append(fi.absoluteFilePath());
+ //FIXME: make separator tweakable
+ classPath.append(':');
+ }
+ QString targetstr = "versions/" + version->id + "/" + version->id + ".jar";
+ QFileInfo fi(targetstr);
+ classPath.append(fi.absoluteFilePath());
+ }
+ 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);
+ proc->setMinecraftArguments(args);
+ proc->setMinecraftWorkdir(rootDir());
+ return proc;
+}
+
+void OneSixInstance::cleanupAfterRun()
+{
+ QString target_dir = PathCombine(rootDir(), "natives/");
+ QDir dir(target_dir);
+ dir.removeRecursively();
}
bool OneSixInstance::setIntendedVersionId ( QString version )
{
settings().set("IntendedVersion", version);
+ setShouldUpdate(true);
}
-QString OneSixInstance::intendedVersionId()
+QString OneSixInstance::intendedVersionId() const
{
return settings().get("IntendedVersion").toString();
}
+
+void OneSixInstance::setShouldUpdate ( bool val )
+{
+ settings().set ( "ShouldUpdate", val );
+}
+
+bool OneSixInstance::shouldUpdate() const
+{
+ I_D(OneSixInstance);
+ QVariant var = settings().get ( "ShouldUpdate" );
+ if ( !var.isValid() || var.toBool() == false )
+ {
+ return intendedVersionId() != currentVersionId();
+ }
+ return true;
+}
+
+QString OneSixInstance::currentVersionId() const
+{
+ return intendedVersionId();
+}
+
+bool OneSixInstance::reloadFullVersion()
+{
+ I_D(OneSixInstance);
+
+ QString verpath = PathCombine(rootDir(), "version.json");
+ QFile versionfile(verpath);
+ if(versionfile.exists() && versionfile.open(QIODevice::ReadOnly))
+ {
+ FullVersionFactory fvf;
+ auto version = fvf.parse(versionfile.readAll());
+ versionfile.close();
+ if(version)
+ {
+ d->version = version;
+ return true;
+ }
+ };
+ return false;
+}
+
+QSharedPointer< FullVersion > OneSixInstance::getFullVersion()
+{
+ I_D(OneSixInstance);
+ return d->version;
+}
diff --git a/backend/OneSixInstance.h b/backend/OneSixInstance.h
index 89e3c9c3..2e08554d 100644
--- a/backend/OneSixInstance.h
+++ b/backend/OneSixInstance.h
@@ -1,6 +1,9 @@
#pragma once
#include "BaseInstance.h"
+#include <QStringList>
+class FullVersion;
+
class LIBMULTIMC_EXPORT OneSixInstance : public BaseInstance
{
Q_OBJECT
@@ -8,8 +11,21 @@ public:
explicit OneSixInstance(const QString &rootDir, SettingsObject * settings, QObject *parent = 0);
virtual OneSixUpdate* doUpdate();
virtual MinecraftProcess* prepareForLaunch ( QString user, QString session );
+ virtual void cleanupAfterRun();
+ virtual QString intendedVersionId() const;
virtual bool setIntendedVersionId ( QString version );
- virtual QString intendedVersionId();
+ virtual QString currentVersionId() const;
+ // virtual void setCurrentVersionId ( QString val ) {};
+
+ virtual bool shouldUpdate() const;
+ virtual void setShouldUpdate(bool val);
+
+ /// reload the full version json file. return true on success!
+ bool reloadFullVersion();
+ /// get the current full version info
+ QSharedPointer<FullVersion> getFullVersion();
+private:
+ QStringList processMinecraftArgs( QString user, QString session );
}; \ No newline at end of file
diff --git a/backend/OneSixInstance_p.h b/backend/OneSixInstance_p.h
index 5bd60155..1037e03c 100644
--- a/backend/OneSixInstance_p.h
+++ b/backend/OneSixInstance_p.h
@@ -1,8 +1,9 @@
#pragma once
-#include <QString>
-#include <settingsobject.h>
+
#include "BaseInstance_p.h"
+#include "OneSixVersion.h"
struct OneSixInstancePrivate: public BaseInstancePrivate
{
+ QSharedPointer<FullVersion> version;
}; \ No newline at end of file
diff --git a/backend/OneSixUpdate.cpp b/backend/OneSixUpdate.cpp
index a344662c..db3b9864 100644
--- a/backend/OneSixUpdate.cpp
+++ b/backend/OneSixUpdate.cpp
@@ -28,6 +28,7 @@
#include "lists/MinecraftVersionList.h"
#include "VersionFactory.h"
#include "OneSixVersion.h"
+#include "OneSixInstance.h"
#include "pathutils.h"
@@ -40,14 +41,28 @@ OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) :
void OneSixUpdate::executeTask()
{
+ QString intendedVersion = m_inst->intendedVersionId();
// Get a pointer to the version object that corresponds to the instance's version.
- targetVersion = (MinecraftVersion *)MinecraftVersionList::getMainList().findVersion(m_inst->intendedVersionId());
- if(targetVersion == NULL)
+ targetVersion = (MinecraftVersion *)MinecraftVersionList::getMainList().findVersion(intendedVersion);
+ if(targetVersion == nullptr)
{
+ // don't do anything if it was invalid
emit gameUpdateComplete();
return;
}
+ if(m_inst->shouldUpdate())
+ {
+ versionFileStart();
+ }
+ else
+ {
+ jarlibStart();
+ }
+}
+
+void OneSixUpdate::versionFileStart()
+{
setStatus("Getting the version files from Mojang.");
QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
@@ -59,71 +74,93 @@ void OneSixUpdate::executeTask()
connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed()));
connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64)));
download_queue.enqueue(specificVersionDownloadJob);
-
- QEventLoop loop;
- loop.exec();
}
void OneSixUpdate::versionFileFinished()
{
JobPtr firstJob = specificVersionDownloadJob->getFirstJob();
auto DlJob = firstJob.dynamicCast<DownloadJob>();
- FullVersionFactory parser;
- auto version = parser.parse(DlJob->m_data);
- if(!version)
+ QString version_id = targetVersion->descriptor();
+ QString inst_dir = m_inst->rootDir();
+ // save the version file in $instanceId/version.json
{
- error(parser.error_string);
- exit(0);
+ QString version1 = PathCombine(inst_dir, "/version.json");
+ ensurePathExists(version1);
+ QFile vfile1 (version1);
+ vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly );
+ vfile1.write(DlJob->m_data);
+ vfile1.close();
}
- // save the version file in $instanceId/version.json and versions/$version/$version.json
- QString version_id = targetVersion->descriptor();
- QString inst_dir = m_inst->rootDir();
- QString version1 = PathCombine(inst_dir, "/version.json");
- QString version2 = QString("versions/") + version_id + "/" + version_id + ".json";
- DownloadJob::ensurePathExists(version1);
- DownloadJob::ensurePathExists(version2);
- QFile vfile1 (version1);
- QFile vfile2 (version2);
- vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly );
- vfile2.open(QIODevice::Truncate | QIODevice::WriteOnly );
- vfile1.write(DlJob->m_data);
- vfile2.write(DlJob->m_data);
- vfile1.close();
- vfile2.close();
+ // save the version file in versions/$version/$version.json
+ /*
+ //QString version2 = QString("versions/") + version_id + "/" + version_id + ".json";
+ //ensurePathExists(version2);
+ //QFile vfile2 (version2);
+ //vfile2.open(QIODevice::Truncate | QIODevice::WriteOnly );
+ //vfile2.write(DlJob->m_data);
+ //vfile2.close();
+ */
+
+ jarlibStart();
+}
+
+void OneSixUpdate::versionFileFailed()
+{
+ error("Failed to download the version description. Try again.");
+ emitEnded();
+}
+
+void OneSixUpdate::jarlibStart()
+{
+ OneSixInstance * inst = (OneSixInstance *) m_inst;
+ bool successful = inst->reloadFullVersion();
+ if(!successful)
+ {
+ error("Failed to load the version description file (version.json). It might be corrupted, missing or simply too new.");
+ emitEnded();
+ return;
+ }
+
+ QSharedPointer<FullVersion> version = inst->getFullVersion();
// download the right jar, save it in versions/$version/$version.jar
QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
- urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".jar";
+ urlstr += version->id + "/" + version->id + ".jar";
QString targetstr ("versions/");
- targetstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".jar";
- auto dljob = DownloadJob::create(QUrl(urlstr), targetstr);
+ targetstr += version->id + "/" + version->id + ".jar";
+ auto dljob = DownloadJob::create(QUrl(urlstr), targetstr);
jarlibDownloadJob.reset(new JobList());
jarlibDownloadJob->add(dljob);
+
+ auto libs = version->getActiveNativeLibs();
+ libs.append(version->getActiveNormalLibs());
+
+ for(auto lib: libs)
+ {
+ QString download_path = lib->downloadPath();
+ QString storage_path = "libraries/" + lib->storagePath();
+ jarlibDownloadJob->add(DownloadJob::create(net_manager, download_path, storage_path));
+ }
connect(jarlibDownloadJob.data(), SIGNAL(finished()), SLOT(jarlibFinished()));
connect(jarlibDownloadJob.data(), SIGNAL(failed()), SLOT(jarlibFailed()));
connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64)));
- // determine and download all the libraries, save them in libraries/whatever...
+
download_queue.enqueue(jarlibDownloadJob);
}
void OneSixUpdate::jarlibFinished()
{
- exit(1);
+ emit gameUpdateComplete();
+ emitEnded();
}
void OneSixUpdate::jarlibFailed()
{
error("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE");
- exit(0);
-}
-
-void OneSixUpdate::versionFileFailed()
-{
- error("Failed to download the version description. Try again.");
- exit(0);
+ emitEnded();
}
void OneSixUpdate::error(const QString &msg)
diff --git a/backend/OneSixUpdate.h b/backend/OneSixUpdate.h
index 27a7bccd..3bab4eca 100644
--- a/backend/OneSixUpdate.h
+++ b/backend/OneSixUpdate.h
@@ -46,16 +46,18 @@ public slots:
private slots:
void updateDownloadProgress(qint64 current, qint64 total);
+ void versionFileStart();
void versionFileFinished();
void versionFileFailed();
+ void jarlibStart();
void jarlibFinished();
void jarlibFailed();
+
signals:
/*!
* \brief Signal emitted when the game update is complete.
- * \param response The login response received from login task.
*/
void gameUpdateComplete();
@@ -70,6 +72,7 @@ private:
QString m_subStatusMsg;
+ QSharedPointer<QNetworkAccessManager> net_manager {new QNetworkAccessManager()};
JobListPtr legacyDownloadJob;
JobListPtr specificVersionDownloadJob;
JobListPtr jarlibDownloadJob;
diff --git a/backend/OneSixVersion.cpp b/backend/OneSixVersion.cpp
index b58870ce..2b2f79f5 100644
--- a/backend/OneSixVersion.cpp
+++ b/backend/OneSixVersion.cpp
@@ -64,12 +64,51 @@ void Library::finalize()
}
}
+void Library::setName ( QString name )
+{
+ m_name = name;
+}
+void Library::setBaseUrl ( QString base_url )
+{
+ m_base_url = base_url;
+}
+void Library::setIsNative()
+{
+ m_is_native = true;
+}
+void Library::addNative ( OpSys os, QString suffix )
+{
+ m_is_native = true;
+ m_native_suffixes[os] = suffix;
+}
+void Library::setRules ( QList< QSharedPointer< Rule > > rules )
+{
+ m_rules = rules;
+}
+bool Library::isActive()
+{
+ return m_is_active;
+}
+bool Library::isNative()
+{
+ return m_is_native;
+}
+QString Library::downloadPath()
+{
+ return m_download_path;
+}
+QString Library::storagePath()
+{
+ return m_storage_path;
+}
+
+
QList<QSharedPointer<Library> > FullVersion::getActiveNormalLibs()
{
QList<QSharedPointer<Library> > output;
for ( auto lib: libraries )
{
- if (lib->getIsActive() && !lib->getIsNative())
+ if (lib->isActive() && !lib->isNative())
{
output.append(lib);
}
@@ -82,10 +121,12 @@ QList<QSharedPointer<Library> > FullVersion::getActiveNativeLibs()
QList<QSharedPointer<Library> > output;
for ( auto lib: libraries )
{
- if (lib->getIsActive() && lib->getIsNative())
+ if (lib->isActive() && lib->isNative())
{
output.append(lib);
}
}
return output;
}
+
+
diff --git a/backend/OneSixVersion.h b/backend/OneSixVersion.h
index 762e8f3e..160d0426 100644
--- a/backend/OneSixVersion.h
+++ b/backend/OneSixVersion.h
@@ -107,11 +107,11 @@ private:
QString m_storage_path;
/// where to download the lib from
QString m_download_path;
- /// is this lib actuall active on the current OS?
+ /// is this lib actually active on the current OS?
bool m_is_active;
-
- // native lib?
+ /// is the library a native?
bool m_is_native;
+ /// native suffixes per OS
QMap<OpSys, QString> m_native_suffixes;
public:
QStringList extract_excludes;
@@ -133,62 +133,25 @@ public:
*/
void finalize();
-
- /**
- * Set the library composite name
- */
- void setName(QString name)
- {
- m_name = name;
- }
-
- /**
- * Set the url base for downloads
- */
- void setBaseUrl(QString base_url)
- {
- m_base_url = base_url;
- }
-
- /**
- * Call this to mark the library as 'native' (it's a zip archive with DLLs)
- */
- void setIsNative()
- {
- m_is_native = true;
- }
-
- /**
- * Attach a name suffix to the specified OS native
- */
- void addNative(OpSys os, QString suffix)
- {
- m_is_native = true;
- m_native_suffixes[os] = suffix;
- }
-
- /**
- * Set the load rules
- */
- void setRules(QList<QSharedPointer<Rule> > rules)
- {
- m_rules = rules;
- }
-
- /**
- * Returns true if the library should be loaded (or extracted, in case of natives)
- */
- bool getIsActive()
- {
- return m_is_active;
- }
- /**
- * Returns true if the library is native
- */
- bool getIsNative()
- {
- return m_is_native;
- }
+ /// Set the library composite name
+ void setName(QString name);
+ /// Set the url base for downloads
+ void setBaseUrl(QString base_url);
+ /// Call this to mark the library as 'native' (it's a zip archive with DLLs)
+ void setIsNative();
+ /// Attach a name suffix to the specified OS native
+ void addNative(OpSys os, QString suffix);
+ /// Set the load rules
+ void setRules(QList<QSharedPointer<Rule> > rules);
+
+ /// Returns true if the library should be loaded (or extracted, in case of natives)
+ bool isActive();
+ /// Returns true if the library is native
+ bool isNative();
+ /// Get the URL to download the library from
+ QString downloadPath();
+ /// Get the relative path where the library should be saved
+ QString storagePath();
};
diff --git a/backend/lists/MinecraftVersionList.cpp b/backend/lists/MinecraftVersionList.cpp
index 4abfbfb8..7f220086 100644
--- a/backend/lists/MinecraftVersionList.cpp
+++ b/backend/lists/MinecraftVersionList.cpp
@@ -172,24 +172,21 @@ MCVListLoadTask::~MCVListLoadTask()
void MCVListLoadTask::executeTask()
{
- // NOTE: this executes in the QThread
setStatus("Loading instance version list...");
netMgr = new QNetworkAccessManager();
vlistReply = netMgr->get(QNetworkRequest(QUrl(QString(MCVLIST_URLBASE) + "versions.json")));
connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded()));
- exec();
}
void MCVListLoadTask::list_downloaded()
{
- // NOTE: this executes in the main thread
-
if(vlistReply->error() != QNetworkReply::QNetworkReply::NoError)
{
qDebug() << "Failed to load Minecraft main version list" << vlistReply->errorString();
vlistReply->deleteLater();
- exit(0);
+ emitEnded();
+ return;
}
QJsonParseError jsonError;
@@ -199,13 +196,15 @@ void MCVListLoadTask::list_downloaded()
if (jsonError.error != QJsonParseError::NoError)
{
qDebug() << "Error parsing version list JSON:" << jsonError.errorString();
- exit(0);
+ emitEnded();
+ return;
}
if(!jsonDoc.isObject())
{
qDebug() << "Error parsing version list JSON: " << "jsonDoc is not an object";
- exit(0);
+ emitEnded();
+ return;
}
QJsonObject root = jsonDoc.object();
@@ -214,7 +213,8 @@ void MCVListLoadTask::list_downloaded()
if(!root.value("latest").isObject())
{
qDebug() << "Error parsing version list JSON: " << "version list is missing 'latest' object";
- exit(0);
+ emitEnded();
+ return;
}
QJsonObject latest = root.value("latest").toObject();
@@ -224,19 +224,22 @@ void MCVListLoadTask::list_downloaded()
if(latestReleaseID.isEmpty())
{
qDebug() << "Error parsing version list JSON: " << "latest release field is missing";
- exit(0);
+ emitEnded();
+ return;
}
if(latestSnapshotID.isEmpty())
{
qDebug() << "Error parsing version list JSON: " << "latest snapshot field is missing";
- exit(0);
+ emitEnded();
+ return;
}
// Now, get the array of versions.
if(!root.value("versions").isArray())
{
qDebug() << "Error parsing version list JSON: " << "version list object is missing 'versions' array";
- exit(0);
+ emitEnded();
+ return;
}
QJsonArray versions = root.value("versions").toArray();
@@ -303,7 +306,8 @@ void MCVListLoadTask::list_downloaded()
#ifdef PRINT_VERSIONS
m_list->printToStdOut();
#endif
- exit(1);
+ emitEnded();
+ return;
}
// FIXME: we should have a local cache of the version list and a local cache of version data
diff --git a/backend/tasks/LoginTask.cpp b/backend/tasks/LoginTask.cpp
index 88cdbacc..30e97ca9 100644
--- a/backend/tasks/LoginTask.cpp
+++ b/backend/tasks/LoginTask.cpp
@@ -27,16 +27,14 @@
LoginTask::LoginTask( const UserInfo& uInfo, QObject* parent ) :
Task(parent), uInfo(uInfo)
{
-
+ netMgr.reset(new QNetworkAccessManager());
}
void LoginTask::executeTask()
{
setStatus("Logging in...");
- QNetworkAccessManager netMgr;
- connect(&netMgr, SIGNAL(finished(QNetworkReply*)),
- SLOT(processNetReply(QNetworkReply*)));
+ connect(netMgr.data(), SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetReply(QNetworkReply*)));
QUrl loginURL("https://login.minecraft.net/");
QNetworkRequest netRequest(loginURL);
@@ -47,8 +45,7 @@ void LoginTask::executeTask()
params.addQueryItem("password", uInfo.password);
params.addQueryItem("version", "13");
- netReply = netMgr.post(netRequest, params.query(QUrl::EncodeSpaces).toUtf8());
- exec();
+ netReply = netMgr->post(netRequest, params.query(QUrl::EncodeSpaces).toUtf8());
}
void LoginTask::processNetReply(QNetworkReply *reply)
@@ -115,6 +112,5 @@ void LoginTask::processNetReply(QNetworkReply *reply)
emit loginFailed("Login failed: " + reply->errorString());
break;
}
-
- quit();
+ emitEnded();
}
diff --git a/backend/tasks/LoginTask.h b/backend/tasks/LoginTask.h
index 3f72bb0b..e2f72f9e 100644
--- a/backend/tasks/LoginTask.h
+++ b/backend/tasks/LoginTask.h
@@ -17,7 +17,7 @@
#define LOGINTASK_H
#include "Task.h"
-
+#include <QSharedPointer>
#include "libmmc_config.h"
struct UserInfo
@@ -33,7 +33,7 @@ struct LoginResponse
qint64 latestVersion;
};
-//class QNetworkAccessManager;
+class QNetworkAccessManager;
class QNetworkReply;
class LIBMULTIMC_EXPORT LoginTask : public Task
@@ -54,6 +54,8 @@ protected:
QNetworkReply* netReply;
UserInfo uInfo;
+private:
+ QSharedPointer<QNetworkAccessManager> netMgr;
};
#endif // LOGINTASK_H
diff --git a/backend/tasks/Task.cpp b/backend/tasks/Task.cpp
index 7831ee58..30dd2d10 100644
--- a/backend/tasks/Task.cpp
+++ b/backend/tasks/Task.cpp
@@ -16,7 +16,7 @@
#include "Task.h"
Task::Task(QObject *parent) :
- QThread(parent)
+ QObject(parent)
{
}
@@ -50,28 +50,30 @@ void Task::setProgress(int progress)
void Task::startTask()
{
- start();
-}
-
-void Task::run()
-{
emitStarted();
executeTask();
- emitEnded();
}
void Task::emitStarted()
{
+ running = true;
emit started();
emit started(this);
}
void Task::emitEnded()
{
+ running = false;
emit ended();
emit ended(this);
}
+bool Task::isRunning() const
+{
+ return running;
+}
+
+
void Task::emitStatusChange(const QString &status)
{
emit statusChanged(status);
diff --git a/backend/tasks/Task.h b/backend/tasks/Task.h
index c8c12c02..bbe27ae1 100644
--- a/backend/tasks/Task.h
+++ b/backend/tasks/Task.h
@@ -17,12 +17,11 @@
#define TASK_H
#include <QObject>
-#include <QThread>
#include <QString>
#include "libmmc_config.h"
-class LIBMULTIMC_EXPORT Task : public QThread
+class LIBMULTIMC_EXPORT Task : public QObject
{
Q_OBJECT
public:
@@ -34,6 +33,8 @@ public:
QString getStatus() const;
int getProgress() const;
+ bool isRunning() const;
+
/*!
* \brief Calculates and sets the task's progress based on the number of parts completed out of the total number to complete.
* This is essentially just shorthand for setProgress((parts / whole) * 100);
@@ -43,7 +44,7 @@ public:
*/
void calcProgress(int parts, int whole);
-public slots:
+protected slots:
void setStatus(const QString& status);
void setProgress(int progress);
@@ -54,7 +55,6 @@ signals:
void started();
void ended();
-
void statusChanged(Task* task, const QString& status);
void progressChanged(Task* task, int progress);
@@ -62,7 +62,6 @@ signals:
void progressChanged(int progress);
protected:
- virtual void run();
virtual void executeTask() = 0;
virtual void emitStarted();
@@ -73,6 +72,7 @@ protected:
QString status;
int progress;
+ bool running = false;
};
#endif // TASK_H