summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-11-25 00:46:52 +0100
committerPetr Mrázek <peterix@gmail.com>2013-11-25 00:46:52 +0100
commit088b039cf7de6b217a289499a8efe5a47e861829 (patch)
tree7fe8861cc33e5bf3ca9a0347b04604a9f9883d81
parent82225a21e1b7f1671a42c1511032c59ecda0503f (diff)
downloadMultiMC-088b039cf7de6b217a289499a8efe5a47e861829.tar
MultiMC-088b039cf7de6b217a289499a8efe5a47e861829.tar.gz
MultiMC-088b039cf7de6b217a289499a8efe5a47e861829.tar.lz
MultiMC-088b039cf7de6b217a289499a8efe5a47e861829.tar.xz
MultiMC-088b039cf7de6b217a289499a8efe5a47e861829.zip
Detect java bitness on launch, use appropriate libraries
Fixes problems with latest snapshot
-rw-r--r--gui/MainWindow.cpp2
-rw-r--r--logic/BaseInstance.h3
-rw-r--r--logic/LegacyInstance.cpp12
-rw-r--r--logic/LegacyInstance.h28
-rw-r--r--logic/LegacyUpdate.cpp6
-rw-r--r--logic/LegacyUpdate.h5
-rw-r--r--logic/OneSixInstance.cpp32
-rw-r--r--logic/OneSixInstance.h29
-rw-r--r--logic/OneSixUpdate.cpp139
-rw-r--r--logic/OneSixUpdate.h14
10 files changed, 165 insertions, 105 deletions
diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp
index 6ae41f50..7a0b5849 100644
--- a/gui/MainWindow.cpp
+++ b/gui/MainWindow.cpp
@@ -599,7 +599,7 @@ void MainWindow::doLogin(const QString &errorMsg)
void MainWindow::prepareLaunch(BaseInstance* instance, MojangAccountPtr account)
{
- Task *updateTask = instance->doUpdate();
+ Task *updateTask = instance->doUpdate(true);
if (!updateTask)
{
launchInstance(instance, account);
diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h
index cf86fda6..2d7537d6 100644
--- a/logic/BaseInstance.h
+++ b/logic/BaseInstance.h
@@ -93,7 +93,6 @@ public:
* \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.
@@ -151,7 +150,7 @@ public:
virtual SettingsObject &settings() const;
/// returns a valid update task if update is needed, NULL otherwise
- virtual Task *doUpdate() = 0;
+ virtual Task *doUpdate(bool prepare_for_launch) = 0;
/// returns a valid minecraft process, ready for launch with the given account.
virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) = 0;
diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp
index ab6536d0..6ac03e76 100644
--- a/logic/LegacyInstance.cpp
+++ b/logic/LegacyInstance.cpp
@@ -44,10 +44,12 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings,
settings->registerSetting(new Setting("IntendedJarVersion", ""));
}
-Task *LegacyInstance::doUpdate()
+Task *LegacyInstance::doUpdate(bool prepare_for_launch)
{
+ // make sure the jar mods list is initialized by asking for it.
auto list = jarModList();
- return new LegacyUpdate(this, this);
+ // create an update task
+ return new LegacyUpdate(this, prepare_for_launch , this);
}
MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account)
@@ -245,12 +247,6 @@ QString LegacyInstance::currentVersionId() const
return d->m_settings->get("JarVersion").toString();
}
-void LegacyInstance::setCurrentVersionId(QString val)
-{
- I_D(LegacyInstance);
- d->m_settings->set("JarVersion", val);
-}
-
QString LegacyInstance::lwjglVersion() const
{
I_D(LegacyInstance);
diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h
index 3d35521e..a17ef281 100644
--- a/logic/LegacyInstance.h
+++ b/logic/LegacyInstance.h
@@ -48,7 +48,7 @@ public:
QString loaderModsDir() const;
QString coreModsDir() const;
QString resourceDir() const;
- virtual QString instanceConfigFolder() const;
+ virtual QString instanceConfigFolder() const override;
/*!
* Whether or not the instance's minecraft.jar needs to be rebuilt.
@@ -58,37 +58,35 @@ public:
bool shouldRebuild() const;
void setShouldRebuild(bool val);
- virtual QString currentVersionId() const;
- virtual void setCurrentVersionId(QString val);
+ virtual QString currentVersionId() const override;
//! 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);
- virtual QString intendedVersionId() const;
- virtual bool setIntendedVersionId(QString version);
+ virtual QString intendedVersionId() const override;
+ virtual bool setIntendedVersionId(QString version) override;
// the `version' of Legacy instances is defined by the launcher code.
// in contrast with OneSix, where `version' is described in a json file
virtual bool versionIsCustom() override
{
return false;
}
- ;
- virtual bool shouldUpdate() const;
- virtual void setShouldUpdate(bool val);
- virtual Task *doUpdate();
+ virtual bool shouldUpdate() const override;
+ virtual void setShouldUpdate(bool val) override;
+ virtual Task *doUpdate(bool prepare_for_launch) override;
- virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account);
- virtual void cleanupAfterRun();
- virtual QDialog *createModEditDialog(QWidget *parent);
+ virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
+ virtual void cleanupAfterRun() override;
+ virtual QDialog *createModEditDialog(QWidget *parent) override;
- virtual QString defaultBaseJar() const;
- virtual QString defaultCustomBaseJar() const;
+ virtual QString defaultBaseJar() const override;
+ virtual QString defaultCustomBaseJar() const override;
bool menuActionEnabled(QString action_name) const;
- virtual QString getStatusbarDescription();
+ virtual QString getStatusbarDescription() override;
protected
slots:
diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp
index 05442917..3fc17351 100644
--- a/logic/LegacyUpdate.cpp
+++ b/logic/LegacyUpdate.cpp
@@ -26,7 +26,8 @@
#include <JlCompress.h>
#include "logger/QsLog.h"
-LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
+LegacyUpdate::LegacyUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent)
+ : Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch)
{
}
@@ -361,7 +362,8 @@ void LegacyUpdate::ModTheJar()
setStatus("Installing mods - backing up minecraft.jar...");
if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
{
- emitFailed("It seems both the active and base jar are gone. A fresh base jar will be used on next run.");
+ emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
+ "be used on next run.");
inst->setShouldRebuild(true);
inst->setShouldUpdate(true);
inst->setShouldUseCustomBaseJar(false);
diff --git a/logic/LegacyUpdate.h b/logic/LegacyUpdate.h
index 8ffdb0f0..d753197f 100644
--- a/logic/LegacyUpdate.h
+++ b/logic/LegacyUpdate.h
@@ -31,7 +31,7 @@ class LegacyUpdate : public Task
{
Q_OBJECT
public:
- explicit LegacyUpdate(BaseInstance *inst, QObject *parent = 0);
+ explicit LegacyUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent = 0);
virtual void executeTask();
private
@@ -71,5 +71,6 @@ private:
private:
NetJobPtr legacyDownloadJob;
- BaseInstance *m_inst;
+ BaseInstance *m_inst = nullptr;
+ bool m_prepare_for_launch = false;
};
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index a947b7c0..27713860 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -37,9 +37,9 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o
reloadFullVersion();
}
-Task *OneSixInstance::doUpdate()
+Task *OneSixInstance::doUpdate(bool prepare_for_launch)
{
- return new OneSixUpdate(this);
+ return new OneSixUpdate(this, prepare_for_launch);
}
QString replaceTokensIn(QString text, QMap<QString, QString> with)
@@ -108,34 +108,12 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account)
{
I_D(OneSixInstance);
- cleanupAfterRun();
+
+ QString natives_dir_raw = PathCombine(instanceRoot(), "natives/");
+
auto version = d->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)
- {
- // FIXME: handle errors
- return nullptr;
- }
-
- for (auto lib : libs_to_extract)
- {
- QString storage = lib->storagePath();
- if(storage.contains("${arch}"))
- {
- storage.replace("${arch}", "64");
- }
- QString path = "libraries/" + lib->storagePath();
- QLOG_INFO() << "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()));
diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h
index e30ca7ca..042c104b 100644
--- a/logic/OneSixInstance.h
+++ b/logic/OneSixInstance.h
@@ -37,23 +37,22 @@ public:
////// Directories //////
QString resourcePacksDir() const;
QString loaderModsDir() const;
- virtual QString instanceConfigFolder() const;
+ virtual QString instanceConfigFolder() const override;
- virtual Task *doUpdate();
- virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account);
+ virtual Task *doUpdate(bool prepare_for_launch) override;
+ virtual MinecraftProcess *prepareForLaunch(MojangAccountPtr account) override;
- virtual void cleanupAfterRun();
+ virtual void cleanupAfterRun() override;
- virtual QString intendedVersionId() const;
- virtual bool setIntendedVersionId(QString version);
+ virtual QString intendedVersionId() const override;
+ virtual bool setIntendedVersionId(QString version) override;
- virtual QString currentVersionId() const;
- // virtual void setCurrentVersionId ( QString val ) {};
+ virtual QString currentVersionId() const override;
- virtual bool shouldUpdate() const;
- virtual void setShouldUpdate(bool val);
+ virtual bool shouldUpdate() const override;
+ virtual void setShouldUpdate(bool val) override;
- virtual QDialog *createModEditDialog(QWidget *parent);
+ virtual QDialog *createModEditDialog(QWidget *parent) override;
/// reload the full version json file. return true on success!
bool reloadFullVersion();
@@ -66,11 +65,11 @@ public:
/// is the current version original, or custom?
virtual bool versionIsCustom() override;
- virtual QString defaultBaseJar() const;
- virtual QString defaultCustomBaseJar() const;
+ virtual QString defaultBaseJar() const override;
+ virtual QString defaultCustomBaseJar() const override;
- virtual bool menuActionEnabled(QString action_name) const;
- virtual QString getStatusbarDescription();
+ virtual bool menuActionEnabled(QString action_name) const override;
+ virtual QString getStatusbarDescription() override;
private:
QStringList processMinecraftArgs(MojangAccountPtr account);
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
index c69ff155..dfb958b2 100644
--- a/logic/OneSixUpdate.cpp
+++ b/logic/OneSixUpdate.cpp
@@ -31,8 +31,10 @@
#include "net/ForgeMirrors.h"
#include "pathutils.h"
+#include <JlCompress.h>
-OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
+OneSixUpdate::OneSixUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent)
+ : Task(parent), m_inst(inst), m_prepare_for_launch(prepare_for_launch)
{
}
@@ -48,28 +50,57 @@ void OneSixUpdate::executeTask()
return;
}
- // Get a pointer to the version object that corresponds to the instance's version.
- targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(
- MMC->minecraftlist()->findVersion(intendedVersion));
- if (targetVersion == nullptr)
- {
- // don't do anything if it was invalid
- emitSucceeded();
- return;
- }
-
if (m_inst->shouldUpdate())
{
+ // Get a pointer to the version object that corresponds to the instance's version.
+ targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(
+ MMC->minecraftlist()->findVersion(intendedVersion));
+ if (targetVersion == nullptr)
+ {
+ // don't do anything if it was invalid
+ emitFailed("The specified Minecraft version is invalid. Choose a different one.");
+ return;
+ }
versionFileStart();
}
else
{
+ checkJava();
+ }
+}
+
+void OneSixUpdate::checkJava()
+{
+ QLOG_INFO() << m_inst->name() << ": checking java binary";
+ setStatus("Testing the Java installation.");
+ // TODO: cache this so we don't have to run an extra java process every time.
+ QString java_path = m_inst->settings().get("JavaPath").toString();
+
+ checker.reset(new JavaChecker());
+ connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
+ SLOT(checkFinished(JavaCheckResult)));
+ checker->performCheck(java_path);
+}
+
+void OneSixUpdate::checkFinished(JavaCheckResult result)
+{
+ if (result.valid)
+ {
+ QLOG_INFO() << m_inst->name() << ": java is "
+ << (result.is_64bit ? "64 bit" : "32 bit");
+ java_is_64bit = result.is_64bit;
jarlibStart();
}
+ else
+ {
+ QLOG_INFO() << m_inst->name() << ": java isn't valid";
+ emitFailed("The java binary doesn't work. Check the settings and correct the problem");
+ }
}
void OneSixUpdate::versionFileStart()
{
+ QLOG_INFO() << m_inst->name() << ": getting version file.";
setStatus("Getting the version files from Mojang.");
QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
@@ -129,7 +160,7 @@ void OneSixUpdate::versionFileFinished()
}
inst->reloadFullVersion();
- jarlibStart();
+ checkJava();
}
void OneSixUpdate::versionFileFailed()
@@ -139,6 +170,8 @@ void OneSixUpdate::versionFileFailed()
void OneSixUpdate::jarlibStart()
{
+ setStatus("Getting the library files from Mojang.");
+ QLOG_INFO() << m_inst->name() << ": downloading libraries";
OneSixInstance *inst = (OneSixInstance *)m_inst;
bool successful = inst->reloadFullVersion();
if (!successful)
@@ -170,26 +203,13 @@ void OneSixUpdate::jarlibStart()
{
if (lib->hint() == "local")
continue;
+ QString subst = java_is_64bit ? "64" : "32";
QString storage = lib->storagePath();
QString dl = lib->downloadUrl();
- if (lib->isNative() && storage.contains("${arch}"))
- {
- auto storage64 = storage, storage32 = storage;
- auto dl64 = dl, dl32 = dl;
- storage64.replace("${arch}", "64");
- storage32.replace("${arch}", "32");
- dl32.replace("${arch}", "32");
- dl64.replace("${arch}", "64");
-
- auto entry64 = metacache->resolveEntry("libraries", storage64);
- if (entry64->stale)
- jarlibDownloadJob->addNetAction(CacheDownload::make(dl64, entry64));
-
- auto entry32 = metacache->resolveEntry("libraries", storage32);
- if (entry32->stale)
- jarlibDownloadJob->addNetAction(CacheDownload::make(dl32, entry32));
- continue;
- }
+
+ storage.replace("${arch}", subst);
+ dl.replace("${arch}", subst);
+
auto entry = metacache->resolveEntry("libraries", storage);
if (entry->stale)
{
@@ -221,7 +241,10 @@ void OneSixUpdate::jarlibStart()
void OneSixUpdate::jarlibFinished()
{
- emitSucceeded();
+ if (m_prepare_for_launch)
+ prepareForLaunch();
+ else
+ emitSucceeded();
}
void OneSixUpdate::jarlibFailed()
@@ -231,3 +254,57 @@ void OneSixUpdate::jarlibFailed()
emitFailed("Failed to download the following files:\n" + failed_all +
"\n\nPlease try again.");
}
+
+void OneSixUpdate::prepareForLaunch()
+{
+ setStatus("Preparing for launch.");
+ QLOG_INFO() << m_inst->name() << ": preparing for launch";
+ auto onesix_inst = (OneSixInstance *)m_inst;
+
+ // delete any leftovers, if they are present.
+ onesix_inst->cleanupAfterRun();
+
+ // Acquire swag
+ QString natives_dir_raw = PathCombine(onesix_inst->instanceRoot(), "natives/");
+ auto version = onesix_inst->getFullVersion();
+ if (!version)
+ {
+ emitFailed("The version information for this instance is not complete. Try re-creating "
+ "it or changing the version.");
+ return;
+ }
+ auto libs_to_extract = version->getActiveNativeLibs();
+
+ // Acquire bag
+ bool success = ensureFolderPathExists(natives_dir_raw);
+ if (!success)
+ {
+ emitFailed("Could not create the native library folder:\n" + natives_dir_raw +
+ "\nMake sure MultiMC has appropriate permissions and there is enough space "
+ "on the storage device.");
+ return;
+ }
+
+ // Put swag in the bag
+ QString subst = java_is_64bit ? "64" : "32";
+ for (auto lib : libs_to_extract)
+ {
+ QString storage = lib->storagePath();
+ storage.replace("${arch}", subst);
+
+ QString path = "libraries/" + storage;
+ QLOG_INFO() << "Will extract " << path.toLocal8Bit();
+ if (JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes)
+ .isEmpty())
+ {
+ emitFailed(
+ "Could not extract the native library:\n" + path +
+ "\nMake sure MultiMC has appropriate permissions and there is enough space "
+ "on the storage device.");
+ return;
+ }
+ }
+
+ // Show them your war face!
+ emitSucceeded();
+}
diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h
index a66da067..b86c205f 100644
--- a/logic/OneSixUpdate.h
+++ b/logic/OneSixUpdate.h
@@ -21,6 +21,7 @@
#include "logic/net/NetJob.h"
#include "logic/tasks/Task.h"
+#include "logic/JavaChecker.h"
class MinecraftVersion;
class BaseInstance;
@@ -29,7 +30,7 @@ class OneSixUpdate : public Task
{
Q_OBJECT
public:
- explicit OneSixUpdate(BaseInstance *inst, QObject *parent = 0);
+ explicit OneSixUpdate(BaseInstance *inst, bool prepare_for_launch, QObject *parent = 0);
virtual void executeTask();
private
@@ -42,11 +43,20 @@ slots:
void jarlibFinished();
void jarlibFailed();
+ void checkJava();
+ void checkFinished(JavaCheckResult result);
+
+ // extract the appropriate libraries
+ void prepareForLaunch();
private:
NetJobPtr specificVersionDownloadJob;
NetJobPtr jarlibDownloadJob;
// target version, determined during this task
std::shared_ptr<MinecraftVersion> targetVersion;
- BaseInstance *m_inst;
+ BaseInstance *m_inst = nullptr;
+ bool m_prepare_for_launch = false;
+ std::shared_ptr<JavaChecker> checker;
+
+ bool java_is_64bit = false;
};