diff options
Diffstat (limited to 'logic')
-rw-r--r-- | logic/BaseInstance.h | 4 | ||||
-rw-r--r-- | logic/BaseUpdate.cpp | 26 | ||||
-rw-r--r-- | logic/BaseUpdate.h | 47 | ||||
-rw-r--r-- | logic/JavaChecker.cpp | 89 | ||||
-rw-r--r-- | logic/JavaChecker.h | 32 | ||||
-rw-r--r-- | logic/JavaUtils.h | 1 | ||||
-rw-r--r-- | logic/LegacyInstance.cpp | 55 | ||||
-rw-r--r-- | logic/LegacyInstance.h | 4 | ||||
-rw-r--r-- | logic/LegacyUpdate.cpp | 2 | ||||
-rw-r--r-- | logic/LegacyUpdate.h | 4 | ||||
-rw-r--r-- | logic/MinecraftProcess.cpp | 4 | ||||
-rw-r--r-- | logic/MinecraftProcess.h | 4 | ||||
-rw-r--r-- | logic/OneSixInstance.cpp | 12 | ||||
-rw-r--r-- | logic/OneSixInstance.h | 4 | ||||
-rw-r--r-- | logic/OneSixUpdate.cpp | 30 | ||||
-rw-r--r-- | logic/OneSixUpdate.h | 4 |
16 files changed, 181 insertions, 141 deletions
diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index b083c24a..6c9b16c7 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -25,7 +25,7 @@ #include "net/LoginTask.h" class QDialog; -class BaseUpdate; +class Task; class MinecraftProcess; class OneSixUpdate; class InstanceList; @@ -151,7 +151,7 @@ public: virtual SettingsObject &settings() const; /// returns a valid update task if update is needed, NULL otherwise - virtual BaseUpdate *doUpdate() = 0; + virtual Task *doUpdate() = 0; /// returns a valid minecraft process, ready for launch virtual MinecraftProcess *prepareForLaunch(LoginResponse response) = 0; diff --git a/logic/BaseUpdate.cpp b/logic/BaseUpdate.cpp deleted file mode 100644 index 5aeb12ef..00000000 --- a/logic/BaseUpdate.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * 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 - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BaseUpdate.h" - -BaseUpdate::BaseUpdate(BaseInstance *inst, QObject *parent) : Task(parent) -{ - m_inst = inst; -} - -void BaseUpdate::updateDownloadProgress(qint64 current, qint64 total) -{ - emit progress(current, total); -}
\ No newline at end of file diff --git a/logic/BaseUpdate.h b/logic/BaseUpdate.h deleted file mode 100644 index ddeefa97..00000000 --- a/logic/BaseUpdate.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * 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 - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <QObject> -#include <QList> -#include <QUrl> - -#include "net/NetJob.h" - -#include "tasks/Task.h" - -class MinecraftVersion; -class BaseInstance; - -/*! - * The game update task is the task that handles downloading instances' files. - */ -class BaseUpdate : public Task -{ - Q_OBJECT -public: - explicit BaseUpdate(BaseInstance *inst, QObject *parent = 0); - - virtual void executeTask() = 0; - -protected -slots: - // virtual void error(const QString &msg); - void updateDownloadProgress(qint64 current, qint64 total); - -protected: - BaseInstance *m_inst; -}; diff --git a/logic/JavaChecker.cpp b/logic/JavaChecker.cpp new file mode 100644 index 00000000..10b84fe1 --- /dev/null +++ b/logic/JavaChecker.cpp @@ -0,0 +1,89 @@ +#include "JavaChecker.h" +#include <QFile> +#include <QProcess> + +#define CHECKER_FILE "JavaChecker.jar" + +JavaChecker::JavaChecker(QObject *parent) : QObject(parent) +{ +} + +int JavaChecker::performCheck(QString path) +{ + if(QFile::exists(CHECKER_FILE)) + { + QFile::remove(CHECKER_FILE); + } + // extract the checker + QFile(":/java/checker.jar").copy(CHECKER_FILE); + + QStringList args = {"-jar", CHECKER_FILE}; + + process.reset(new QProcess()); + process->setArguments(args); + process->setProgram(path); + process->setProcessChannelMode(QProcess::SeparateChannels); + + connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(finished(int, QProcess::ExitStatus))); + connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, + SLOT(error(QProcess::ProcessError))); + connect(&killTimer, SIGNAL(timeout()), SLOT(timeout())); + killTimer.setSingleShot(true); + killTimer.start(5000); + process->start(); +} + +void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) +{ + killTimer.stop(); + QProcessPtr _process; + _process.swap(process); + + if (status == QProcess::CrashExit || exitcode == 1) + { + emit checkFinished({}); + return; + } + + QString p_stdout = _process->readAllStandardOutput(); + auto parts = p_stdout.split('=', QString::SkipEmptyParts); + if (parts.size() != 2 || parts[0] != "os.arch") + { + emit checkFinished({}); + return; + } + + auto os_arch = parts[1].remove('\n').remove('\r'); + bool is_64 = os_arch == "x86_64" || os_arch == "amd64"; + + JavaCheckResult result; + { + result.valid = true; + result.is_64bit = is_64; + result.mojangPlatform = is_64 ? "64" : "32"; + result.realPlatform = os_arch; + } + emit checkFinished(result); +} + +void JavaChecker::error(QProcess::ProcessError err) +{ + if(err == QProcess::FailedToStart) + { + killTimer.stop(); + emit checkFinished({}); + return; + } +} + +void JavaChecker::timeout() +{ + // NO MERCY. NO ABUSE. + if(process) + { + process->kill(); + process.reset(); + emit checkFinished({}); + } +} diff --git a/logic/JavaChecker.h b/logic/JavaChecker.h new file mode 100644 index 00000000..60f8b56f --- /dev/null +++ b/logic/JavaChecker.h @@ -0,0 +1,32 @@ +#pragma once +#include <QProcess> +#include <QTimer> +#include <memory> + +struct JavaCheckResult +{ + QString mojangPlatform; + QString realPlatform; + bool valid = false; + bool is_64bit = false; +}; +typedef std::shared_ptr<QProcess> QProcessPtr; + +class JavaChecker : public QObject +{ + Q_OBJECT +public: + explicit JavaChecker(QObject *parent = 0); + int performCheck(QString path); + +signals: + void checkFinished(JavaCheckResult result); +private: + QProcessPtr process; + QTimer killTimer; +public +slots: + void timeout(); + void finished(int exitcode, QProcess::ExitStatus); + void error(QProcess::ProcessError); +}; diff --git a/logic/JavaUtils.h b/logic/JavaUtils.h index 8d7550d0..44f576b4 100644 --- a/logic/JavaUtils.h +++ b/logic/JavaUtils.h @@ -33,7 +33,6 @@ public: QList<JavaVersionPtr> FindJavaPaths(); JavaVersionPtr GetDefaultJava(); - private: #if WINDOWS diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 9a91b839..07e302f5 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -44,7 +44,7 @@ LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, settings->registerSetting(new Setting("IntendedJarVersion", "")); } -BaseUpdate *LegacyInstance::doUpdate() +Task *LegacyInstance::doUpdate() { auto list = jarModList(); return new LegacyUpdate(this, this); @@ -59,7 +59,7 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(LoginResponse response) pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG"); // extract the legacy launcher - QFile(":/launcher/launcher.jar").copy(PathCombine(minecraftRoot(), LAUNCHER_FILE)); + QFile(":/java/launcher.jar").copy(PathCombine(minecraftRoot(), LAUNCHER_FILE)); // set the process arguments { @@ -108,11 +108,11 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(LoginResponse response) args << windowTitle; args << windowSize; args << lwjgl; - proc->setMinecraftArguments(args); + proc->setArguments(args); } // set the process work path - proc->setMinecraftWorkdir(minecraftRoot()); + proc->setWorkdir(minecraftRoot()); return proc; } @@ -227,56 +227,18 @@ QString LegacyInstance::instanceConfigFolder() const return PathCombine(minecraftRoot(), "config"); } -/* -bool LegacyInstance::shouldUpdateCurrentVersion() const -{ - QFileInfo jar(runnableJar()); - return jar.lastModified().toUTC().toMSecsSinceEpoch() != lastCurrentVersionUpdate(); -} - -void LegacyInstance::updateCurrentVersion(bool keepCurrent) -{ - QFileInfo jar(runnableJar()); - - if(!jar.exists()) - { - setLastCurrentVersionUpdate(0); - setCurrentVersionId("Unknown"); - return; - } - - qint64 time = jar.lastModified().toUTC().toMSecsSinceEpoch(); - - setLastCurrentVersionUpdate(time); - if (!keepCurrent) - { - // TODO: Implement GetMinecraftJarVersion function. - QString newVersion = -"Unknown";//javautils::GetMinecraftJarVersion(jar.absoluteFilePath()); - setCurrentVersionId(newVersion); - } -} -qint64 LegacyInstance::lastCurrentVersionUpdate() const -{ - I_D(LegacyInstance); - return d->m_settings->get ( "lastVersionUpdate" ).value<qint64>(); -} -void LegacyInstance::setLastCurrentVersionUpdate ( qint64 val ) -{ - I_D(LegacyInstance); - d->m_settings->set ( "lastVersionUpdate", val ); -} -*/ bool LegacyInstance::shouldRebuild() const { I_D(LegacyInstance); return d->m_settings->get("NeedsRebuild").toBool(); } + void LegacyInstance::setShouldRebuild(bool val) { I_D(LegacyInstance); d->m_settings->set("NeedsRebuild", val); } + QString LegacyInstance::currentVersionId() const { I_D(LegacyInstance); @@ -294,22 +256,26 @@ QString LegacyInstance::lwjglVersion() const I_D(LegacyInstance); return d->m_settings->get("LwjglVersion").toString(); } + void LegacyInstance::setLWJGLVersion(QString val) { I_D(LegacyInstance); d->m_settings->set("LwjglVersion", val); } + QString LegacyInstance::intendedVersionId() const { I_D(LegacyInstance); return d->m_settings->get("IntendedJarVersion").toString(); } + bool LegacyInstance::setIntendedVersionId(QString version) { settings().set("IntendedJarVersion", version); setShouldUpdate(true); return true; } + bool LegacyInstance::shouldUpdate() const { I_D(LegacyInstance); @@ -320,6 +286,7 @@ bool LegacyInstance::shouldUpdate() const } return true; } + void LegacyInstance::setShouldUpdate(bool val) { settings().set("ShouldUpdate", val); diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h index 8a8d4b91..04b16b9b 100644 --- a/logic/LegacyInstance.h +++ b/logic/LegacyInstance.h @@ -18,7 +18,7 @@ #include "BaseInstance.h" class ModList; -class BaseUpdate; +class Task; class LegacyInstance : public BaseInstance { @@ -78,7 +78,7 @@ public: virtual bool shouldUpdate() const; virtual void setShouldUpdate(bool val); - virtual BaseUpdate *doUpdate(); + virtual Task *doUpdate(); virtual MinecraftProcess *prepareForLaunch(LoginResponse response); virtual void cleanupAfterRun(); diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index 8ba97827..05442917 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -26,7 +26,7 @@ #include <JlCompress.h> #include "logger/QsLog.h" -LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : BaseUpdate(inst, parent) +LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst) { } diff --git a/logic/LegacyUpdate.h b/logic/LegacyUpdate.h index b30fa0b3..8ffdb0f0 100644 --- a/logic/LegacyUpdate.h +++ b/logic/LegacyUpdate.h @@ -21,14 +21,13 @@ #include "logic/net/NetJob.h" #include "logic/tasks/Task.h" -#include "logic/BaseUpdate.h" class MinecraftVersion; class BaseInstance; class QuaZip; class Mod; -class LegacyUpdate : public BaseUpdate +class LegacyUpdate : public Task { Q_OBJECT public: @@ -72,4 +71,5 @@ private: private: NetJobPtr legacyDownloadJob; + BaseInstance *m_inst; }; diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index b3b587e8..e4a26054 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -59,12 +59,12 @@ MinecraftProcess::MinecraftProcess(BaseInstance *inst) : m_instance(inst) connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); } -void MinecraftProcess::setMinecraftArguments(QStringList args) +void MinecraftProcess::setArguments(QStringList args) { m_args = args; } -void MinecraftProcess::setMinecraftWorkdir(QString path) +void MinecraftProcess::setWorkdir(QString path) { QDir mcDir(path); this->setWorkingDirectory(mcDir.absolutePath()); diff --git a/logic/MinecraftProcess.h b/logic/MinecraftProcess.h index 6d4a1eb7..e38d2f83 100644 --- a/logic/MinecraftProcess.h +++ b/logic/MinecraftProcess.h @@ -63,9 +63,9 @@ public: return m_instance; } - void setMinecraftWorkdir(QString path); + void setWorkdir(QString path); - void setMinecraftArguments(QStringList args); + void setArguments(QStringList args); void killMinecraft(); diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 7e0d48fd..7764d225 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -18,6 +18,7 @@ #include "OneSixUpdate.h" #include "MinecraftProcess.h" #include "OneSixVersion.h" +#include "JavaChecker.h" #include <setting.h> #include <pathutils.h> @@ -36,7 +37,7 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o reloadFullVersion(); } -BaseUpdate *OneSixInstance::doUpdate() +Task *OneSixInstance::doUpdate() { return new OneSixUpdate(this); } @@ -122,6 +123,11 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(LoginResponse response) 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) @@ -188,8 +194,8 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(LoginResponse response) // create the process and set its parameters MinecraftProcess *proc = new MinecraftProcess(this); - proc->setMinecraftArguments(args); - proc->setMinecraftWorkdir(minecraftRoot()); + proc->setArguments(args); + proc->setWorkdir(minecraftRoot()); return proc; } diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index 2d02b605..2d44ddba 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -20,7 +20,7 @@ #include "BaseInstance.h" class OneSixVersion; -class BaseUpdate; +class Task; class ModList; class OneSixInstance : public BaseInstance @@ -39,7 +39,7 @@ public: QString loaderModsDir() const; virtual QString instanceConfigFolder() const; - virtual BaseUpdate *doUpdate(); + virtual Task *doUpdate(); virtual MinecraftProcess *prepareForLaunch(LoginResponse response); virtual void cleanupAfterRun(); diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 62d95ee6..c69ff155 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -32,7 +32,7 @@ #include "pathutils.h" -OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) : BaseUpdate(inst, parent) +OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst) { } @@ -143,7 +143,7 @@ void OneSixUpdate::jarlibStart() bool successful = inst->reloadFullVersion(); if (!successful) { - emitFailed("Failed to load the version description file (version.json). It might be " + emitFailed("Failed to load the version description file. It might be " "corrupted, missing or simply too new."); return; } @@ -170,16 +170,36 @@ void OneSixUpdate::jarlibStart() { if (lib->hint() == "local") continue; - auto entry = metacache->resolveEntry("libraries", lib->storagePath()); + 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; + } + auto entry = metacache->resolveEntry("libraries", storage); if (entry->stale) { if (lib->hint() == "forge-pack-xz") { - ForgeLibs.append(ForgeXzDownload::make(lib->storagePath(), entry)); + ForgeLibs.append(ForgeXzDownload::make(storage, entry)); } else { - jarlibDownloadJob->addNetAction(CacheDownload::make(lib->downloadUrl(), entry)); + jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry)); } } } diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h index e5f553c7..a66da067 100644 --- a/logic/OneSixUpdate.h +++ b/logic/OneSixUpdate.h @@ -21,12 +21,11 @@ #include "logic/net/NetJob.h" #include "logic/tasks/Task.h" -#include "logic/BaseUpdate.h" class MinecraftVersion; class BaseInstance; -class OneSixUpdate : public BaseUpdate +class OneSixUpdate : public Task { Q_OBJECT public: @@ -49,4 +48,5 @@ private: // target version, determined during this task std::shared_ptr<MinecraftVersion> targetVersion; + BaseInstance *m_inst; }; |