diff options
| author | Petr Mrázek <peterix@gmail.com> | 2014-12-18 02:48:14 +0100 |
|---|---|---|
| committer | Petr Mrázek <peterix@gmail.com> | 2014-12-27 20:50:33 +0100 |
| commit | a30a9559c749446165ec84e737fe85b44a462584 (patch) | |
| tree | 9e6bfadfc4e10f01ab2580c33e2c682d57b4ce99 /logic | |
| parent | 01f44e0f39a808d3d5285c394d83a8fc80421890 (diff) | |
| download | PrismLauncher-a30a9559c749446165ec84e737fe85b44a462584.tar.gz PrismLauncher-a30a9559c749446165ec84e737fe85b44a462584.tar.bz2 PrismLauncher-a30a9559c749446165ec84e737fe85b44a462584.zip | |
NOISSUE Fix jar mods for OnesSix
Diffstat (limited to 'logic')
| -rw-r--r-- | logic/BaseInstance.cpp | 183 | ||||
| -rw-r--r-- | logic/BaseInstance.h | 37 | ||||
| -rw-r--r-- | logic/BaseInstance_p.h | 36 | ||||
| -rw-r--r-- | logic/InstanceFactory.cpp | 3 | ||||
| -rw-r--r-- | logic/InstanceLauncher.cpp | 94 | ||||
| -rw-r--r-- | logic/InstanceLauncher.h | 44 | ||||
| -rw-r--r-- | logic/JarUtils.cpp | 161 | ||||
| -rw-r--r-- | logic/JarUtils.h | 18 | ||||
| -rw-r--r-- | logic/LegacyInstance.cpp | 109 | ||||
| -rw-r--r-- | logic/LegacyInstance.h | 30 | ||||
| -rw-r--r-- | logic/LegacyInstance_p.h | 32 | ||||
| -rw-r--r-- | logic/LegacyUpdate.cpp | 160 | ||||
| -rw-r--r-- | logic/LegacyUpdate.h | 9 | ||||
| -rw-r--r-- | logic/ModList.h | 5 | ||||
| -rw-r--r-- | logic/OneSixFTBInstance.cpp | 1 | ||||
| -rw-r--r-- | logic/OneSixInstance.cpp | 97 | ||||
| -rw-r--r-- | logic/OneSixInstance.h | 23 | ||||
| -rw-r--r-- | logic/OneSixInstance_p.h | 33 | ||||
| -rw-r--r-- | logic/OneSixUpdate.cpp | 121 | ||||
| -rw-r--r-- | logic/OneSixUpdate.h | 4 | ||||
| -rw-r--r-- | logic/URNResolver.cpp | 98 | ||||
| -rw-r--r-- | logic/URNResolver.h | 18 | ||||
| -rw-r--r-- | logic/minecraft/VersionFile.cpp | 1 |
23 files changed, 436 insertions, 881 deletions
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index 1dc5b671..b23dde73 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -15,7 +15,6 @@ #include "MultiMC.h" #include "BaseInstance.h" -#include "BaseInstance_p.h" #include <QFileInfo> #include <QDir> @@ -31,61 +30,50 @@ #include "logic/icons/IconList.h" #include "logic/InstanceList.h" -BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir, - SettingsObject *settings_obj, QObject *parent) - : QObject(parent), inst_d(d_in) +BaseInstance::BaseInstance(const QString &rootDir, SettingsObject *settings, QObject *parent) + : QObject(parent) { - I_D(BaseInstance); - d->m_settings = std::shared_ptr<SettingsObject>(settings_obj); - d->m_rootDir = rootDir; - settings().registerSetting("name", "Unnamed Instance"); - settings().registerSetting("iconKey", "default"); + m_settings = std::shared_ptr<SettingsObject>(settings); + m_rootDir = rootDir; + + m_settings->registerSetting("name", "Unnamed Instance"); + m_settings->registerSetting("iconKey", "default"); connect(MMC->icons().get(), SIGNAL(iconUpdated(QString)), SLOT(iconUpdated(QString))); - settings().registerSetting("notes", ""); - settings().registerSetting("lastLaunchTime", 0); - - /* - * custom base jar has no default. it is determined in code... see the accessor methods for - *it - * - * for instances that DO NOT have the CustomBaseJar setting (legacy instances), - * [.]minecraft/bin/mcbackup.jar is the default base jar - */ - settings().registerSetting("UseCustomBaseJar", true); - settings().registerSetting("CustomBaseJar", ""); + m_settings->registerSetting("notes", ""); + m_settings->registerSetting("lastLaunchTime", 0); auto globalSettings = MMC->settings(); // Java Settings - settings().registerSetting("OverrideJava", false); - settings().registerSetting("OverrideJavaLocation", false); - settings().registerSetting("OverrideJavaArgs", false); - settings().registerOverride(globalSettings->getSetting("JavaPath")); - settings().registerOverride(globalSettings->getSetting("JvmArgs")); + m_settings->registerSetting("OverrideJava", false); + m_settings->registerSetting("OverrideJavaLocation", false); + m_settings->registerSetting("OverrideJavaArgs", false); + m_settings->registerOverride(globalSettings->getSetting("JavaPath")); + m_settings->registerOverride(globalSettings->getSetting("JvmArgs")); // Custom Commands - settings().registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); - settings().registerOverride(globalSettings->getSetting("PreLaunchCommand")); - settings().registerOverride(globalSettings->getSetting("PostExitCommand")); + m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); + m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand")); + m_settings->registerOverride(globalSettings->getSetting("PostExitCommand")); // Window Size - settings().registerSetting("OverrideWindow", false); - settings().registerOverride(globalSettings->getSetting("LaunchMaximized")); - settings().registerOverride(globalSettings->getSetting("MinecraftWinWidth")); - settings().registerOverride(globalSettings->getSetting("MinecraftWinHeight")); + m_settings->registerSetting("OverrideWindow", false); + m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized")); + m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth")); + m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight")); // Memory - settings().registerSetting("OverrideMemory", false); - settings().registerOverride(globalSettings->getSetting("MinMemAlloc")); - settings().registerOverride(globalSettings->getSetting("MaxMemAlloc")); - settings().registerOverride(globalSettings->getSetting("PermGen")); + m_settings->registerSetting("OverrideMemory", false); + m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc")); + m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc")); + m_settings->registerOverride(globalSettings->getSetting("PermGen")); // Console - settings().registerSetting("OverrideConsole", false); - settings().registerOverride(globalSettings->getSetting("ShowConsole")); - settings().registerOverride(globalSettings->getSetting("AutoCloseConsole")); - settings().registerOverride(globalSettings->getSetting("LogPrePostOutput")); + m_settings->registerSetting("OverrideConsole", false); + m_settings->registerOverride(globalSettings->getSetting("ShowConsole")); + m_settings->registerOverride(globalSettings->getSetting("AutoCloseConsole")); + m_settings->registerOverride(globalSettings->getSetting("LogPrePostOutput")); } void BaseInstance::iconUpdated(QString key) @@ -109,26 +97,22 @@ QString BaseInstance::id() const bool BaseInstance::isRunning() const { - I_D(BaseInstance); - return d->m_isRunning; + return m_isRunning; } -void BaseInstance::setRunning(bool running) const +void BaseInstance::setRunning(bool running) { - I_D(BaseInstance); - d->m_isRunning = running; + m_isRunning = running; } QString BaseInstance::instanceType() const { - I_D(BaseInstance); - return d->m_settings->get("InstanceType").toString(); + return m_settings->get("InstanceType").toString(); } QString BaseInstance::instanceRoot() const { - I_D(BaseInstance); - return d->m_rootDir; + return m_rootDir; } QString BaseInstance::minecraftRoot() const @@ -159,36 +143,34 @@ std::shared_ptr<BaseVersionList> BaseInstance::versionList() const SettingsObject &BaseInstance::settings() const { - I_D(BaseInstance); - return *d->m_settings; + return *m_settings; } BaseInstance::InstanceFlags BaseInstance::flags() const { - I_D(const BaseInstance); - return d->m_flags; + return m_flags; } + void BaseInstance::setFlags(const InstanceFlags &flags) { - I_D(BaseInstance); - if (flags != d->m_flags) + if (flags != m_flags) { - d->m_flags = flags; + m_flags = flags; emit flagsChanged(); emit propertiesChanged(this); } } + void BaseInstance::setFlag(const BaseInstance::InstanceFlag flag) { - I_D(BaseInstance); - d->m_flags |= flag; + m_flags |= flag; emit flagsChanged(); emit propertiesChanged(this); } + void BaseInstance::unsetFlag(const BaseInstance::InstanceFlag flag) { - I_D(BaseInstance); - d->m_flags &= ~flag; + m_flags &= ~flag; emit flagsChanged(); emit propertiesChanged(this); } @@ -200,69 +182,23 @@ bool BaseInstance::canLaunch() const bool BaseInstance::reload() { - return settings().reload(); -} - -QString BaseInstance::baseJar() const -{ - I_D(BaseInstance); - bool customJar = d->m_settings->get("UseCustomBaseJar").toBool(); - if (customJar) - { - return customBaseJar(); - } - else - return defaultBaseJar(); -} - -QString BaseInstance::customBaseJar() const -{ - I_D(BaseInstance); - QString value = d->m_settings->get("CustomBaseJar").toString(); - if (value.isNull() || value.isEmpty()) - { - return defaultCustomBaseJar(); - } - return value; -} - -void BaseInstance::setCustomBaseJar(QString val) -{ - I_D(BaseInstance); - if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar()) - d->m_settings->reset("CustomBaseJar"); - else - d->m_settings->set("CustomBaseJar", val); -} - -void BaseInstance::setShouldUseCustomBaseJar(bool val) -{ - I_D(BaseInstance); - d->m_settings->set("UseCustomBaseJar", val); -} - -bool BaseInstance::shouldUseCustomBaseJar() const -{ - I_D(BaseInstance); - return d->m_settings->get("UseCustomBaseJar").toBool(); + return m_settings->reload(); } qint64 BaseInstance::lastLaunch() const { - I_D(BaseInstance); - return d->m_settings->get("lastLaunchTime").value<qint64>(); + return m_settings->get("lastLaunchTime").value<qint64>(); } + void BaseInstance::setLastLaunch(qint64 val) { - I_D(BaseInstance); - d->m_settings->set("lastLaunchTime", val); + m_settings->set("lastLaunchTime", val); emit propertiesChanged(this); } void BaseInstance::setGroupInitial(QString val) { - I_D(BaseInstance); - d->m_group = val; + m_group = val; emit propertiesChanged(this); } @@ -274,44 +210,39 @@ void BaseInstance::setGroupPost(QString val) QString BaseInstance::group() const { - I_D(BaseInstance); - return d->m_group; + return m_group; } void BaseInstance::setNotes(QString val) { - I_D(BaseInstance); - d->m_settings->set("notes", val); + m_settings->set("notes", val); } + QString BaseInstance::notes() const { - I_D(BaseInstance); - return d->m_settings->get("notes").toString(); + return m_settings->get("notes").toString(); } void BaseInstance::setIconKey(QString val) { - I_D(BaseInstance); - d->m_settings->set("iconKey", val); + m_settings->set("iconKey", val); emit propertiesChanged(this); } + QString BaseInstance::iconKey() const { - I_D(BaseInstance); - return d->m_settings->get("iconKey").toString(); + return m_settings->get("iconKey").toString(); } void BaseInstance::setName(QString val) { - I_D(BaseInstance); - d->m_settings->set("name", val); + m_settings->set("name", val); emit propertiesChanged(this); } QString BaseInstance::name() const { - I_D(BaseInstance); - return d->m_settings->get("name").toString(); + return m_settings->get("name").toString(); } QString BaseInstance::windowTitle() const diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index c8517298..a0ac3c57 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -51,8 +51,7 @@ class BaseInstance : public QObject Q_OBJECT protected: /// no-touchy! - BaseInstance(BaseInstancePrivate *d, const QString &rootDir, SettingsObject *settings, - QObject *parent = 0); + BaseInstance(const QString &rootDir, SettingsObject *settings, QObject *parent = 0); public: /// virtual destructor to make sure the destruction is COMPLETE @@ -69,8 +68,8 @@ public: /// be unique. virtual QString id() const; - virtual void setRunning(bool running) const; - virtual bool isRunning() const; + void setRunning(bool running); + bool isRunning() const; /// get the type of this instance QString instanceType() const; @@ -127,30 +126,10 @@ public: { return nullptr; } - + /// Traits. Normally inside the version, depends on instance implementation. virtual QSet <QString> traits() = 0; - /// Get the curent base jar of this instance. By default, it's the - /// versions/$version/$version.jar - QString baseJar() const; - - /// the default base jar of this instance - virtual QString defaultBaseJar() const = 0; - /// the default custom base jar of this instance - virtual QString defaultCustomBaseJar() const = 0; - - /*! - * Whether or not custom base jar is used - */ - bool shouldUseCustomBaseJar() const; - void setShouldUseCustomBaseJar(bool val); - /*! - * The value of the custom base jar - */ - QString customBaseJar() const; - void setCustomBaseJar(QString val); - /** * Gets the time that the instance was last launched. * Stored in milliseconds since epoch. @@ -202,7 +181,7 @@ public: VersionBrokenFlag = 0x01, UpdateAvailable = 0x02 }; - Q_DECLARE_FLAGS(InstanceFlags, InstanceFlag) + Q_DECLARE_FLAGS(InstanceFlags, InstanceFlag); InstanceFlags flags() const; void setFlags(const InstanceFlags &flags); void setFlag(const InstanceFlag flag); @@ -232,7 +211,11 @@ protected slots: void iconUpdated(QString key); protected: - std::shared_ptr<BaseInstancePrivate> inst_d; + QString m_rootDir; + QString m_group; + std::shared_ptr<SettingsObject> m_settings; + InstanceFlags m_flags; + bool m_isRunning = false; }; Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>) diff --git a/logic/BaseInstance_p.h b/logic/BaseInstance_p.h deleted file mode 100644 index 2958e4e8..00000000 --- a/logic/BaseInstance_p.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2013-2014 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 <QString> -#include <QSet> - -#include "logic/settings/SettingsObject.h" - -#include "BaseInstance.h" - -#define I_D(Class) Class##Private *const d = (Class##Private * const)inst_d.get() - -class BaseInstancePrivate -{ -public: - virtual ~BaseInstancePrivate(){}; - QString m_rootDir; - QString m_group; - std::shared_ptr<SettingsObject> m_settings; - BaseInstance::InstanceFlags m_flags; - bool m_isRunning = false; -}; diff --git a/logic/InstanceFactory.cpp b/logic/InstanceFactory.cpp index 640c02f3..832b8387 100644 --- a/logic/InstanceFactory.cpp +++ b/logic/InstanceFactory.cpp @@ -100,7 +100,6 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in m_settings->set("InstanceType", "OneSix"); inst.reset(new OneSixInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); - inst->setShouldUseCustomBaseJar(false); } else if (type == FTBInstance) { @@ -109,14 +108,12 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in m_settings->set("InstanceType", "LegacyFTB"); inst.reset(new LegacyFTBInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); - inst->setShouldUseCustomBaseJar(false); } else { m_settings->set("InstanceType", "OneSixFTB"); inst.reset(new OneSixFTBInstance(instDir, m_settings)); inst->setIntendedVersionId(version->descriptor()); - inst->setShouldUseCustomBaseJar(false); } } else diff --git a/logic/InstanceLauncher.cpp b/logic/InstanceLauncher.cpp deleted file mode 100644 index 4e47c592..00000000 --- a/logic/InstanceLauncher.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2013-2014 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 <iostream> - -#include "InstanceLauncher.h" -#include "MultiMC.h" - -#include "gui/ConsoleWindow.h" -#include "gui/dialogs/ProgressDialog.h" - -#include "logic/MinecraftProcess.h" -#include "logic/InstanceList.h" - -InstanceLauncher::InstanceLauncher(QString instId) : QObject(), instId(instId) -{ -} - -void InstanceLauncher::onTerminated() -{ - std::cout << "Minecraft exited" << std::endl; - MMC->quit(); -} - -void InstanceLauncher::onLoginComplete() -{ - // TODO: Fix this. - /* - LoginTask *task = (LoginTask *)QObject::sender(); - auto result = task->getResult(); - auto instance = MMC->instances()->getInstanceById(instId); - proc = instance->prepareForLaunch(result); - if (!proc) - { - // FIXME: report error - return; - } - console = new ConsoleWindow(proc); - connect(console, SIGNAL(isClosing()), this, SLOT(onTerminated())); - - proc->setLogin(result.username, result.session_id); - proc->launch(); - */ -} - -void InstanceLauncher::doLogin(const QString &errorMsg) -{ - // FIXME: Use new account system here... - /* - LoginDialog *loginDlg = new LoginDialog(nullptr, errorMsg); - loginDlg->exec(); - if (loginDlg->result() == QDialog::Accepted) - { - PasswordLogin uInfo{loginDlg->getUsername(), loginDlg->getPassword()}; - - ProgressDialog *tDialog = new ProgressDialog(nullptr); - LoginTask *loginTask = new LoginTask(uInfo, tDialog); - connect(loginTask, SIGNAL(succeeded()), SLOT(onLoginComplete()), Qt::QueuedConnection); - connect(loginTask, SIGNAL(failed(QString)), SLOT(doLogin(QString)), - Qt::QueuedConnection); - tDialog->exec(loginTask); - } - */ - // onLoginComplete(LoginResponse("Offline","Offline", 1)); -} - -int InstanceLauncher::launch() -{ - std::cout << "Launching Instance '" << qPrintable(instId) << "'" << std::endl; - auto instance = MMC->instances()->getInstanceById(instId); - if (!instance) - { - std::cout << "Could not find instance requested. note that you have to specify the ID, " - "not the NAME" << std::endl; - return 1; - } - - std::cout << "Logging in..." << std::endl; - doLogin(""); - - return MMC->exec(); -} diff --git a/logic/InstanceLauncher.h b/logic/InstanceLauncher.h deleted file mode 100644 index 07f86b99..00000000 --- a/logic/InstanceLauncher.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2013-2014 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> - -class MinecraftProcess; -class ConsoleWindow; - -// Commandline instance launcher -class InstanceLauncher : public QObject -{ - Q_OBJECT - -private: - QString instId; - MinecraftProcess *proc; - ConsoleWindow *console; - -public: - InstanceLauncher(QString instId); - -private -slots: - void onTerminated(); - void onLoginComplete(); - void doLogin(const QString &errorMsg); - -public: - int launch(); -}; diff --git a/logic/JarUtils.cpp b/logic/JarUtils.cpp new file mode 100644 index 00000000..3b4f780a --- /dev/null +++ b/logic/JarUtils.cpp @@ -0,0 +1,161 @@ +#include "JarUtils.h" +#include <quazip.h> +#include <quazipfile.h> +#include <JlCompress.h> +#include <logger/QsLog.h> + +namespace JarUtils { + +bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, + std::function<bool(QString)> filter) +{ + QuaZip modZip(from.filePath()); + modZip.open(QuaZip::mdUnzip); + + QuaZipFile fileInsideMod(&modZip); + QuaZipFile zipOutFile(into); + for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile()) + { + QString filename = modZip.getCurrentFileName(); + if (!filter(filename)) + { + QLOG_INFO() << "Skipping file " << filename << " from " + << from.fileName() << " - filtered"; + continue; + } + if (contained.contains(filename)) + { + QLOG_INFO() << "Skipping already contained file " << filename << " from " + << from.fileName(); + continue; + } + contained.insert(filename); + QLOG_INFO() << "Adding file " << filename << " from " << from.fileName(); + + if (!fileInsideMod.open(QIODevice::ReadOnly)) + { + QLOG_ERROR() << "Failed to open " << filename << " from " << from.fileName(); + return false; + } + + QuaZipNewInfo info_out(fileInsideMod.getActualFileName()); + + if (!zipOutFile.open(QIODevice::WriteOnly, info_out)) + { + QLOG_ERROR() << "Failed to open " << filename << " in the jar"; + fileInsideMod.close(); + return false; + } + if (!JlCompress::copyData(fileInsideMod, zipOutFile)) + { + zipOutFile.close(); + fileInsideMod.close(); + QLOG_ERROR() << "Failed to copy data of " << filename << " into the jar"; + return false; + } + zipOutFile.close(); + fileInsideMod.close(); + } + return true; +} + +bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods) +{ + QuaZip zipOut(targetJarPath); + if (!zipOut.open(QuaZip::mdCreate)) + { + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to open the minecraft.jar for modding"; + return false; + } + // Files already added to the jar. + // These files will be skipped. + QSet<QString> addedFiles; + + // Modify the jar + QListIterator<Mod> i(mods); + i.toBack(); + while (i.hasPrevious()) + { + const Mod &mod = i.previous(); + // do not merge disabled mods. + if (!mod.enabled()) + continue; + if (mod.type() == Mod::MOD_ZIPFILE) + { + if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles, noFilter)) + { + zipOut.close(); + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to add" << mod.filename().fileName() << "to the jar."; + return false; + } + } + else if (mod.type() == Mod::MOD_SINGLEFILE) + { + auto filename = mod.filename(); + if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), + filename.fileName())) + { + zipOut.close(); + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to add" << mod.filename().fileName() << "to the jar."; + return false; + } + addedFiles.insert(filename.fileName()); + QLOG_INFO() << "Adding file " << filename.fileName() << " from " + << filename.absoluteFilePath(); + } + else if (mod.type() == Mod::MOD_FOLDER) + { + auto filename = mod.filename(); + QString what_to_zip = filename.absoluteFilePath(); + QDir dir(what_to_zip); + dir.cdUp(); + QString parent_dir = dir.absolutePath(); + if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, true, addedFiles)) + { + zipOut.close(); + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to add" << mod.filename().fileName() << "to the jar."; + return false; + } + QLOG_INFO() << "Adding folder " << filename.fileName() << " from " + << filename.absoluteFilePath(); + } + } + + if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, metaInfFilter)) + { + zipOut.close(); + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to insert minecraft.jar contents."; + return false; + } + + // Recompress the jar + zipOut.close(); + if (zipOut.getZipError() != 0) + { + QFile::remove(targetJarPath); + QLOG_ERROR() << "Failed to finalize minecraft.jar!"; + return false; + } + return true; +} + +bool noFilter(QString) +{ + return true; +} + +bool metaInfFilter(QString key) +{ + if(key.contains("META-INF")) + { + return false; + } + return true; +} + +} diff --git a/logic/JarUtils.h b/logic/JarUtils.h new file mode 100644 index 00000000..2e8bd2a7 --- /dev/null +++ b/logic/JarUtils.h @@ -0,0 +1,18 @@ +#pragma once +#include <QString> +#include <QFileInfo> +#include <QSet> +#include "Mod.h" +#include <functional> + +class QuaZip; +namespace JarUtils +{ + bool noFilter(QString); + bool metaInfFilter(QString key); + + bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, + std::function<bool(QString)> filter); + + bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods); +} diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 468110da..7752229a 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -23,7 +23,6 @@ #include "MultiMC.h" #include "LegacyInstance.h" -#include "LegacyInstance_p.h" #include "logic/MinecraftProcess.h" #include "logic/LegacyUpdate.h" @@ -36,15 +35,23 @@ #include <gui/pages/NotesPage.h> #include <gui/pages/ScreenshotsPage.h> -LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, - QObject *parent) - : BaseInstance(new LegacyInstancePrivate(), rootDir, settings, parent) +LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, QObject *parent) + : BaseInstance(rootDir, settings, parent) { settings->registerSetting("NeedsRebuild", true); settings->registerSetting("ShouldUpdate", false); settings->registerSetting("JarVersion", "Unknown"); settings->registerSetting("LwjglVersion", "2.9.0"); settings->registerSetting("IntendedJarVersion", ""); + /* + * custom base jar has no default. it is determined in code... see the accessor methods for + *it + * + * for instances that DO NOT have the CustomBaseJar setting (legacy instances), + * [.]minecraft/bin/mcbackup.jar is the default base jar + */ + settings->registerSetting("UseCustomBaseJar", true); + settings->registerSetting("CustomBaseJar", ""); } QList<BasePage *> LegacyInstance::getPages() @@ -69,6 +76,46 @@ QString LegacyInstance::dialogTitle() return tr("Edit Instance (%1)").arg(name()); } +QString LegacyInstance::baseJar() const +{ + bool customJar = m_settings->get("UseCustomBaseJar").toBool(); + if (customJar) + { + return customBaseJar(); + } + else + return defaultBaseJar(); +} + +QString LegacyInstance::customBaseJar() const +{ + QString value = m_settings->get("CustomBaseJar").toString(); + if (value.isNull() || value.isEmpty()) + { + return defaultCustomBaseJar(); + } + return value; +} + +void LegacyInstance::setCustomBaseJar(QString val) +{ + if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar()) + m_settings->reset("CustomBaseJar"); + else + m_settings->set("CustomBaseJar", val); +} + +void LegacyInstance::setShouldUseCustomBaseJar(bool val) +{ + m_settings->set("UseCustomBaseJar", val); +} + +bool LegacyInstance::shouldUseCustomBaseJar() const +{ + return m_settings->get("UseCustomBaseJar").toBool(); +} + + std::shared_ptr<Task> LegacyInstance::doUpdate() { // make sure the jar mods list is initialized by asking for it. @@ -113,26 +160,24 @@ void LegacyInstance::cleanupAfterRun() std::shared_ptr<ModList> LegacyInstance::coreModList() { - I_D(LegacyInstance); - if (!d->core_mod_list) + if (!core_mod_list) { - d->core_mod_list.reset(new ModList(coreModsDir())); + core_mod_list.reset(new ModList(coreModsDir())); } - d->core_mod_list->update(); - return d->core_mod_list; + core_mod_list->update(); + return core_mod_list; } std::shared_ptr<ModList> LegacyInstance::jarModList() { - I_D(LegacyInstance); - if (!d->jar_mod_list) + if (!jar_mod_list) { auto list = new ModList(jarModsDir(), modListFile()); connect(list, SIGNAL(changed()), SLOT(jarModsChanged())); - d->jar_mod_list.reset(list); + jar_mod_list.reset(list); } - d->jar_mod_list->update(); - return d->jar_mod_list; + jar_mod_list->update(); + return jar_mod_list; } void LegacyInstance::jarModsChanged() @@ -143,24 +188,22 @@ void LegacyInstance::jarModsChanged() std::shared_ptr<ModList> LegacyInstance::loaderModList() { - I_D(LegacyInstance); - if (!d->loader_mod_list) + if (!loader_mod_list) { - d->loader_mod_list.reset(new ModList(loaderModsDir())); + loader_mod_list.reset(new ModList(loaderModsDir())); } - d->loader_mod_list->update(); - return d->loader_mod_list; |
