summaryrefslogtreecommitdiffstats
path: root/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2014-12-18 02:48:14 +0100
committerPetr Mrázek <peterix@gmail.com>2014-12-27 20:50:33 +0100
commita30a9559c749446165ec84e737fe85b44a462584 (patch)
tree9e6bfadfc4e10f01ab2580c33e2c682d57b4ce99 /logic
parent01f44e0f39a808d3d5285c394d83a8fc80421890 (diff)
downloadMultiMC-a30a9559c749446165ec84e737fe85b44a462584.tar
MultiMC-a30a9559c749446165ec84e737fe85b44a462584.tar.gz
MultiMC-a30a9559c749446165ec84e737fe85b44a462584.tar.lz
MultiMC-a30a9559c749446165ec84e737fe85b44a462584.tar.xz
MultiMC-a30a9559c749446165ec84e737fe85b44a462584.zip
NOISSUE Fix jar mods for OnesSix
Diffstat (limited to 'logic')
-rw-r--r--logic/BaseInstance.cpp183
-rw-r--r--logic/BaseInstance.h37
-rw-r--r--logic/BaseInstance_p.h36
-rw-r--r--logic/InstanceFactory.cpp3
-rw-r--r--logic/InstanceLauncher.cpp94
-rw-r--r--logic/InstanceLauncher.h44
-rw-r--r--logic/JarUtils.cpp161
-rw-r--r--logic/JarUtils.h18
-rw-r--r--logic/LegacyInstance.cpp109
-rw-r--r--logic/LegacyInstance.h30
-rw-r--r--logic/LegacyInstance_p.h32
-rw-r--r--logic/LegacyUpdate.cpp160
-rw-r--r--logic/LegacyUpdate.h9
-rw-r--r--logic/ModList.h5
-rw-r--r--logic/OneSixFTBInstance.cpp1
-rw-r--r--logic/OneSixInstance.cpp97
-rw-r--r--logic/OneSixInstance.h23
-rw-r--r--logic/OneSixInstance_p.h33
-rw-r--r--logic/OneSixUpdate.cpp121
-rw-r--r--logic/OneSixUpdate.h4
-rw-r--r--logic/URNResolver.cpp98
-rw-r--r--logic/URNResolver.h18
-rw-r--r--logic/minecraft/VersionFile.cpp1
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;
+ loader_mod_list->update();
+ return loader_mod_list;
}
std::shared_ptr<ModList> LegacyInstance::texturePackList()
{
- I_D(LegacyInstance);
- if (!d->texture_pack_list)
+ if (!texture_pack_list)
{
- d->texture_pack_list.reset(new ModList(texturePacksDir()));
+ texture_pack_list.reset(new ModList(texturePacksDir()));
}
- d->texture_pack_list->update();
- return d->texture_pack_list;
+ texture_pack_list->update();
+ return texture_pack_list;
}
QString LegacyInstance::jarModsDir() const
@@ -219,38 +262,32 @@ QString LegacyInstance::instanceConfigFolder() const
bool LegacyInstance::shouldRebuild() const
{
- I_D(LegacyInstance);
- return d->m_settings->get("NeedsRebuild").toBool();
+ return m_settings->get("NeedsRebuild").toBool();
}
void LegacyInstance::setShouldRebuild(bool val)
{
- I_D(LegacyInstance);
- d->m_settings->set("NeedsRebuild", val);
+ m_settings->set("NeedsRebuild", val);
}
QString LegacyInstance::currentVersionId() const
{
- I_D(LegacyInstance);
- return d->m_settings->get("JarVersion").toString();
+ return m_settings->get("JarVersion").toString();
}
QString LegacyInstance::lwjglVersion() const
{
- I_D(LegacyInstance);
- return d->m_settings->get("LwjglVersion").toString();
+ return m_settings->get("LwjglVersion").toString();
}
void LegacyInstance::setLWJGLVersion(QString val)
{
- I_D(LegacyInstance);
- d->m_settings->set("LwjglVersion", val);
+ m_settings->set("LwjglVersion", val);
}
QString LegacyInstance::intendedVersionId() const
{
- I_D(LegacyInstance);
- return d->m_settings->get("IntendedJarVersion").toString();
+ return m_settings->get("IntendedJarVersion").toString();
}
bool LegacyInstance::setIntendedVersionId(QString version)
diff --git a/logic/LegacyInstance.h b/logic/LegacyInstance.h
index d21d2ff4..b91be7c1 100644
--- a/logic/LegacyInstance.h
+++ b/logic/LegacyInstance.h
@@ -56,6 +56,27 @@ public:
QString resourceDir() const;
virtual QString instanceConfigFolder() const override;
+ /// 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
+ QString defaultBaseJar() const;
+ /// the default custom base jar of this instance
+ QString defaultCustomBaseJar() const;
+
+ /*!
+ * 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);
+
/*!
* 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
@@ -92,11 +113,14 @@ public:
virtual bool prepareForLaunch(AuthSessionPtr account, QString & launchScript) override;
virtual void cleanupAfterRun() override;
- virtual QString defaultBaseJar() const override;
- virtual QString defaultCustomBaseJar() const override;
-
virtual QString getStatusbarDescription() override;
+protected:
+ std::shared_ptr<ModList> jar_mod_list;
+ std::shared_ptr<ModList> core_mod_list;
+ std::shared_ptr<ModList> loader_mod_list;
+ std::shared_ptr<ModList> texture_pack_list;
+
protected
slots:
virtual void jarModsChanged();
diff --git a/logic/LegacyInstance_p.h b/logic/LegacyInstance_p.h
deleted file mode 100644
index 83bcecc5..00000000
--- a/logic/LegacyInstance_p.h
+++ /dev/null
@@ -1,32 +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 "logic/settings/SettingsObject.h"
-#include <memory>
-
-#include "BaseInstance_p.h"
-#include "ModList.h"
-
-class LegacyInstancePrivate : public BaseInstancePrivate
-{
-public:
- virtual ~LegacyInstancePrivate() {};
- std::shared_ptr<ModList> jar_mod_list;
- std::shared_ptr<ModList> core_mod_list;
- std::shared_ptr<ModList> loader_mod_list;
- std::shared_ptr<ModList> texture_pack_list;
-};
diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp
index de5c19c0..10128f57 100644
--- a/logic/LegacyUpdate.cpp
+++ b/logic/LegacyUpdate.cpp
@@ -30,6 +30,7 @@
#include "logger/QsLog.h"
#include "logic/net/URLConstants.h"
+#include "JarUtils.h"
LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
@@ -38,25 +39,7 @@ LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent),
void LegacyUpdate::executeTask()
{
- /*
- if(m_only_prepare)
- {
- // FIXME: think this through some more.
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
- {
- ModTheJar();
- }
- else
- {
- emitSucceeded();
- }
- }
- else
- {
- */
fmllibsStart();
- //}
}
void LegacyUpdate::fmllibsStart()
@@ -415,65 +398,6 @@ void LegacyUpdate::jarFailed()
emitFailed("Failed to download the minecraft jar. Try again later.");
}
-bool LegacyUpdate::MergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
- MetainfAction metainf)
-{
- setStatus(tr("Installing mods: Adding ") + from.fileName() + " ...");
-
- 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 (filename.contains("META-INF") && metainf == LegacyUpdate::IgnoreMetainf)
- {
- QLOG_INFO() << "Skipping META-INF " << filename << " from " << from.fileName();
- 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;
- }
- /*
- QuaZipFileInfo old_info;
- fileInsideMod.getFileInfo(&old_info);
- */
- QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
- /*
- info_out.externalAttr = old_info.externalAttr;
- */
- 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;
-}
-
void LegacyUpdate::ModTheJar()
{
LegacyInstance *inst = (LegacyInstance *)m_inst;
@@ -531,85 +455,13 @@ void LegacyUpdate::ModTheJar()
// TaskStep(); // STEP 1
setStatus(tr("Installing mods: Opening minecraft.jar ..."));
- QuaZip zipOut(runnableJar.filePath());
- if (!zipOut.open(QuaZip::mdCreate))
- {
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to open the minecraft.jar for modding");
- return;
- }
- // Files already added to the jar.
- // These files will be skipped.
- QSet<QString> addedFiles;
-
- // Modify the jar
- setStatus(tr("Installing mods: Adding mod files..."));
- for (int i = modList->size() - 1; i >= 0; i--)
- {
- auto &mod = modList->operator[](i);
-
- // do not merge disabled mods.
- if (!mod.enabled())
- continue;
-
- if (mod.type() == Mod::MOD_ZIPFILE)
- {
- if (!MergeZipFiles(&zipOut, mod.filename(), addedFiles, LegacyUpdate::KeepMetainf))
- {
- zipOut.close();
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to add " + mod.filename().fileName() + " to the jar.");
- return;
- }
- }
- else if (mod.type() == Mod::MOD_SINGLEFILE)
- {
- auto filename = mod.filename();
- if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(),
- filename.fileName()))
- {
- zipOut.close();
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to add " + filename.fileName() + " to the jar");
- return;
- }
- 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(runnableJar.filePath());
- emitFailed("Failed to add " + filename.fileName() + " to the jar");
- return;
- }
- QLOG_INFO() << "Adding folder " << filename.fileName() << " from "
- << filename.absoluteFilePath();
- }
- }
-
- if (!MergeZipFiles(&zipOut, baseJar, addedFiles, LegacyUpdate::IgnoreMetainf))
- {
- zipOut.close();
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to insert minecraft.jar contents.");
- return;
- }
+ const auto & mods = modList->allMods();
+ QString outputJarPath = runnableJar.filePath();
+ QString inputJarPath = baseJar.filePath();
- // Recompress the jar
- zipOut.close();
- if (zipOut.getZipError() != 0)
+ if(!JarUtils::createModdedJar(inputJarPath, outputJarPath, mods))
{
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to finalize minecraft.jar!");
+ emitFailed(tr("Failed to create the custom Minecraft jar file."));
return;
}
inst->setShouldRebuild(false);
diff --git a/logic/LegacyUpdate.h b/logic/LegacyUpdate.h
index da538d2f..8041305a 100644
--- a/logic/LegacyUpdate.h
+++ b/logic/LegacyUpdate.h
@@ -54,15 +54,6 @@ slots:
void ModTheJar();
private:
- enum MetainfAction
- {
- KeepMetainf, // the META-INF folder will be added from the merged jar
- IgnoreMetainf // the META-INF from the merged jar will be ignored
- };
- bool MergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
- MetainfAction metainf);
-
-private:
std::shared_ptr<QNetworkReply> m_reply;
diff --git a/logic/ModList.h b/logic/ModList.h
index e7320df5..2409a31a 100644
--- a/logic/ModList.h
+++ b/logic/ModList.h
@@ -126,6 +126,11 @@ public:
return m_dir;
}
+ const QList<Mod> & allMods()
+ {
+ return mods;
+ }
+
private:
void internalSort(QList<Mod> & what);
struct OrderItem
diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp
index d1585155..bf1361dd 100644
--- a/logic/OneSixFTBInstance.cpp
+++ b/logic/OneSixFTBInstance.cpp
@@ -6,7 +6,6 @@
#include "tasks/SequentialTask.h"
#include "forge/ForgeInstaller.h"
#include "forge/ForgeVersionList.h"
-#include "OneSixInstance_p.h"
#include "MultiMC.h"
#include "pathutils.h"
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index dbf47ffb..40b87d9e 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -21,7 +21,6 @@
#include "logic/OneSixInstance.h"
-#include "logic/OneSixInstance_p.h"
#include "logic/OneSixUpdate.h"
#include "logic/minecraft/InstanceVersion.h"
#include "minecraft/VersionBuildError.h"
@@ -39,13 +38,11 @@
#include "gui/pages/ScreenshotsPage.h"
#include "gui/pages/OtherLogsPage.h"
-OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings,
- QObject *parent)
- : BaseInstance(new OneSixInstancePrivate(), rootDir, settings, parent)
+OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, QObject *parent)
+ : BaseInstance(rootDir, settings, parent)
{
- I_D(OneSixInstance);
- d->m_settings->registerSetting("IntendedVersion", "");
- d->version.reset(new InstanceVersion(this, this));
+ m_settings->registerSetting("IntendedVersion", "");
+ version.reset(new InstanceVersion(this, this));
}
void OneSixInstance::init()
@@ -184,8 +181,6 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr<InstanceVersion> version)
QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
{
- I_D(OneSixInstance);
- auto version = d->version;
QString args_pattern = version->minecraftArguments;
for (auto tweaker : version->tweakers)
{
@@ -207,7 +202,7 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
QString absRootDir = QDir(minecraftRoot()).absolutePath();
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
- token_mapping["game_assets"] = reconstructAssets(d->version).absolutePath();
+ token_mapping["game_assets"] = reconstructAssets(version).absolutePath();
token_mapping["user_properties"] = session->serializeUserProperties();
token_mapping["user_type"] = session->user_type;
@@ -225,13 +220,11 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
bool OneSixInstance::prepareForLaunch(AuthSessionPtr session, QString &launchScript)
{
- I_D(OneSixInstance);
QIcon icon = MMC->icons()->getIcon(iconKey());
auto pixmap = icon.pixmap(128, 128);
pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
- auto version = d->version;
if (!version)
return nullptr;
@@ -242,20 +235,15 @@ bool OneSixInstance::prepareForLaunch(AuthSessionPtr session, QString &launchScr
{
launchScript += "cp " + librariesPath().absoluteFilePath(lib->storagePath()) + "\n";
}
- QString minecraftjarpath;
if (version->hasJarMods())
{
- for (auto jarmod : version->jarMods)
- {
- launchScript += "cp " + jarmodsPath().absoluteFilePath(jarmod->name) + "\n";
- }
- minecraftjarpath = version->id + "/" + version->id + "-stripped.jar";
+ launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("temp.jar") + "\n";
}
else
{
- minecraftjarpath = version->id + "/" + version->id + ".jar";
+ QString relpath = version->id + "/" + version->id + ".jar";
+ launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n";
}
- launchScript += "cp " + versionsPath().absoluteFilePath(minecraftjarpath) + "\n";
}
if (!version->mainClass.isEmpty())
{
@@ -320,46 +308,42 @@ void OneSixInstance::cleanupAfterRun()
std::shared_ptr<ModList> OneSixInstance::loaderModList()
{
- I_D(OneSixInstance);
- 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;
+ loader_mod_list->update();
+ return loader_mod_list;
}
std::shared_ptr<ModList> OneSixInstance::coreModList()
{
- I_D(OneSixInstance);
- 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> OneSixInstance::resourcePackList()
{
- I_D(OneSixInstance);
- if (!d->resource_pack_list)
+ if (!resource_pack_list)
{
- d->resource_pack_list.reset(new ModList(resourcePacksDir()));
+ resource_pack_list.reset(new ModList(resourcePacksDir()));
}
- d->resource_pack_list->update();
- return d->resource_pack_list;
+ resource_pack_list->update();
+ return resource_pack_list;
}
std::shared_ptr<ModList> OneSixInstance::texturePackList()
{
- I_D(OneSixInstance);
- if (!d->texture_pack_list)
+ if (!texture_pack_list)
{
- d->texture_pack_list.reset(new ModList(texturePacksDir()));
+ texture_pack_list.reset(new ModList(texturePacksDir()));
}
- d->texture_pack_list->update();
- return d->texture_pack_list;
+ texture_pack_list->update();
+ return texture_pack_list;
}
bool OneSixInstance::setIntendedVersionId(QString version)
@@ -386,22 +370,18 @@ bool OneSixInstance::shouldUpdate() const
bool OneSixInstance::versionIsCustom()
{
- I_D(const OneSixInstance);
- auto ver = d->version;
- if (ver)
+ if (version)
{
- return !ver->isVanilla();
+ return !version->isVanilla();
}
return false;
}
bool OneSixInstance::versionIsFTBPack()
{
- I_D(const OneSixInstance);
- auto ver = d->version;
- if (ver)
+ if (version)
{
- return ver->hasFtbPack();
+ return version->hasFtbPack();
}
return false;
}
@@ -413,11 +393,10 @@ QString OneSixInstance::currentVersionId() const
void OneSixInstance::reloadVersion()
{
- I_D(OneSixInstance);
try
{
- d->version->reload(externalPatches());
+ version->reload(externalPatches());
unsetFlag(VersionBrokenFlag);
emit versionReloaded();
}
@@ -426,7 +405,7 @@ void OneSixInstance::reloadVersion()
}
catch (MMCError &error)
{
- d->version->clear();
+ version->clear();
setFlag(VersionBrokenFlag);
// TODO: rethrow to show some error message(s)?
emit versionReloaded();
@@ -436,25 +415,13 @@ void OneSixInstance::reloadVersion()
void OneSixInstance::clearVersion()
{
- I_D(OneSixInstance);
- d->version->clear();
+ version->clear();
emit versionReloaded();
}
std::shared_ptr<InstanceVersion> OneSixInstance::getFullVersion() const
{
- I_D(const OneSixInstance);
- return d->version;
-}
-
-QString OneSixInstance::defaultBaseJar() const
-{
- return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
-}
-
-QString OneSixInstance::defaultCustomBaseJar() const
-{
- return PathCombine(instanceRoot(), "custom.jar");
+ return version;
}
QString OneSixInstance::getStatusbarDescription()
diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h
index d751ffc8..70726208 100644
--- a/logic/OneSixInstance.h
+++ b/logic/OneSixInstance.h
@@ -42,7 +42,7 @@ public:
std::shared_ptr<ModList> texturePackList() override;
virtual QSet<QString> traits();
-
+
////// Directories and files //////
QString jarModsDir() const;
QString resourcePacksDir() const;
@@ -67,26 +67,23 @@ public:
/**
* reload the full version json files.
- *
+ *
* throws various exceptions :3
*/
void reloadVersion();
-
+
/// clears all version information in preparation for an update
void clearVersion();
-
+
/// get the current full version info
std::shared_ptr<InstanceVersion> getFullVersion() const;
-
+
/// is the current version original, or custom?
virtual bool versionIsCustom() override;
-
+
/// does this instance have an FTB pack patch inside?
bool versionIsFTBPack();
- virtual QString defaultBaseJar() const override;
- virtual QString defaultCustomBaseJar() const override;
-
virtual QString getStatusbarDescription() override;
virtual QDir jarmodsPath() const;
@@ -107,6 +104,14 @@ signals:
private:
QStringList processMinecraftArgs(AuthSessionPtr account);
QDir reconstructAssets(std::shared_ptr<InstanceVersion> version);
+
+protected:
+ std::shared_ptr<InstanceVersion> version;
+ std::shared_ptr<ModList> jar_mod_list;
+ std::shared_ptr<ModList> loader_mod_list;
+ std::shared_ptr<ModList> core_mod_list;
+ std::shared_ptr<ModList> resource_pack_list;
+ std::shared_ptr<ModList> texture_pack_list;
};
Q_DECLARE_METATYPE(std::shared_ptr<OneSixInstance>)
diff --git a/logic/OneSixInstance_p.h b/logic/OneSixInstance_p.h
deleted file mode 100644
index 3fa12baf..00000000
--- a/logic/OneSixInstance_p.h
+++ /dev/null
@@ -1,33 +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 "logic/BaseInstance_p.h"
-
-class ModList;
-class InstanceVersion;
-
-class OneSixInstancePrivate : public BaseInstancePrivate
-{
-public:
- virtual ~OneSixInstancePrivate() {};
- std::shared_ptr<InstanceVersion> version;
- std::shared_ptr<ModList> jar_mod_list;
- std::shared_ptr<ModList> loader_mod_list;
- std::shared_ptr<ModList> core_mod_list;
- std::shared_ptr<ModList> resource_pack_list;
- std::shared_ptr<ModList> texture_pack_list;
-};
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
index 380d5dab..fe8cf3b5 100644
--- a/logic/OneSixUpdate.cpp
+++ b/logic/OneSixUpdate.cpp
@@ -33,6 +33,7 @@
#include "logic/forge/ForgeMirrors.h"
#include "logic/net/URLConstants.h"
#include "logic/assets/AssetsUtils.h"
+#include "JarUtils.h"
OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
@@ -287,23 +288,44 @@ void OneSixUpdate::jarlibFinished()
OneSixInstance *inst = (OneSixInstance *)m_inst;
std::shared_ptr<InstanceVersion> version = inst->getFullVersion();
+ // nuke obsolete stripped jar(s) if needed
+ QString version_id = version->id;
+ QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
+ QFile strippedJar(strippedPath);
+ if(strippedJar.exists())
+ {
+ strippedJar.remove();
+ }
+ auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
+ QFile finalJar(finalJarPath);
+ if(finalJar.exists())
+ {
+ if(!finalJar.remove())
+ {
+ emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
+ return;
+ }
+ }
+
// create stripped jar, if needed
if (version->hasJarMods())
{
- // FIXME: good candidate for moving elsewhere (jar location resolving/version caching).
- QString version_id = version->id;
+ auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar");
QString localPath = version_id + "/" + version_id + ".jar";
- QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
auto metacache = MMC->metacache();
auto entry = metacache->resolveEntry("versions", localPath);
- auto entryStripped = metacache->resolveEntry("versions", strippedPath);
-
QString fullJarPath = entry->getFullPath();
- QString fullStrippedJarPath = entryStripped->getFullPath();
- QFileInfo finfo(fullStrippedJarPath);
- if (entry->md5sum != jarHashOnEntry || !finfo.exists())
+ //FIXME: remove need to convert to different objects here
+ QList<Mod> mods;
+ for (auto jarmod : version->jarMods)
+ {
+ QString filePath = m_inst->jarmodsPath().absoluteFilePath(jarmod->name);
+ mods.push_back(Mod(QFileInfo(filePath)));
+ }
+ if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, mods))
{
- stripJar(fullJarPath, fullStrippedJarPath);
+ emitFailed(tr("Failed to create the custom Minecraft jar file."));
+ return;
}
}
if (version->traits.contains("legacyFML"))
@@ -324,87 +346,6 @@ void OneSixUpdate::jarlibFailed()
tr("Failed to download the following files:\n%1\n\nPlease try again.").arg(failed_all));
}
-void OneSixUpdate::stripJar(QString origPath, QString newPath)
-{
- QFileInfo runnableJar(newPath);
- if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
- {
- emitFailed("Failed to delete old minecraft.jar");
- return;
- }
-
- // TaskStep(); // STEP 1
- setStatus(tr("Creating stripped jar: Opening minecraft.jar ..."));
-
- QuaZip zipOut(runnableJar.filePath());
- if (!zipOut.open(QuaZip::mdCreate))
- {
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to open the minecraft.jar for stripping");
- return;
- }
- // Modify the jar
- setStatus(tr("Creating stripped jar: Adding files..."));
- if (!MergeZipFiles(&zipOut, origPath))
- {
- zipOut.close();
- QFile::remove(runnableJar.filePath());
- emitFailed("Failed to add " + origPath + " to the jar.");
- return;
- }
-}
-
-bool OneSixUpdate::MergeZipFiles(QuaZip *into, QString from)
-{
- setStatus(tr("Installing mods: Adding ") + from + " ...");
-
- QuaZip modZip(from);
- modZip.open(QuaZip::mdUnzip);
-
- QuaZipFile fileInsideMod(&modZip);
- QuaZipFile zipOutFile(into);
- for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
- {
- QString filename = modZip.getCurrentFileName();
- if (filename.contains("META-INF"))
- {
- QLOG_INFO() << "Skipping META-INF " << filename << " from " << from;
- continue;
- }
- QLOG_INFO() << "Adding file " << filename << " from " << from;
-
- if (!fileInsideMod.open(QIODevice::ReadOnly))
- {
- QLOG_ERROR() << "Failed to open " << filename << " from " << from;
- return false;
- }
- /*
- QuaZipFileInfo old_info;
- fileInsideMod.getFileInfo(&old_info);
- */
- QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
- /*
- info_out.externalAttr = old_info.externalAttr;
- */
- 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;
-}
-
void OneSixUpdate::fmllibsStart()
{
// Get the mod list
diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h
index 2cad7408..5bbe86ba 100644
--- a/logic/OneSixUpdate.h
+++ b/logic/OneSixUpdate.h
@@ -53,8 +53,6 @@ slots:
void assetsFinished();
void assetsFailed();
- void stripJar(QString origPath, QString newPath);
- bool MergeZipFiles(QuaZip *into, QString from);
private:
NetJobPtr jarlibDownloadJob;
NetJobPtr legacyDownloadJob;
@@ -63,7 +61,7 @@ private:
std::shared_ptr<MinecraftVersion> targetVersion;
/// the task that is spawned for version updates
std::shared_ptr<Task> versionUpdateTask;
-
+
OneSixInstance *m_inst = nullptr;
QString jarHashOnEntry;
QList<FMLlib> fmlLibsToProcess;
diff --git a/logic/URNResolver.cpp b/logic/URNResolver.cpp
deleted file mode 100644
index b6bdcf41..00000000
--- a/logic/URNResolver.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "URNResolver.h"
-#include <logger/QsLog.h>
-#include "MultiMC.h"
-#include "logic/forge/ForgeVersionList.h"
-#include "logic/forge/ForgeVersion.h"
-
-QString unescapeNSS(QString RawNSS)
-{
- QString NSS;
- NSS.reserve(RawNSS.size());
- enum
- {
- Normal,
- FirstHex,
- SecondHex
- } ParseState = Normal;
-
- QByteArray translator(" ");
-
- for (auto ch : RawNSS)
- {
- if(ParseState == Normal)
- {
- if(ch == '%')
- {
- ParseState = FirstHex;
- continue;
- }
- else
- {
- NSS.append(ch);
- }
- }
- if(ParseState == FirstHex)
- {
- translator[0] = ch.toLower().unicode();
- ParseState = SecondHex;
- }
- else if(ParseState == SecondHex)
- {
- translator[1] = ch.toLower().unicode();
- auto result = QByteArray::fromHex(translator);
- if (result[0] == '\0')
- return NSS;
- NSS.append(result);
- ParseState = Normal;
- }
- }
- return NSS;
-}
-
-bool URNResolver::parse(const QString &URN, QString &NID, QString &NSS)
-{
- QRegExp URNPattern(
- "^urn:([a-z0-9][a-z0-9-]{0,31}):(([a-z0-9()+,\\-.:=@;$_!*']|%[0-9a-f]{2})+).*",
- Qt::CaseInsensitive);
- if (URNPattern.indexIn(URN) == -1)
- return false;
- auto captures = URNPattern.capturedTexts();
- QString RawNID = captures[1];
- QString RawNSS = captures[2];
-
- NID = RawNID.toLower();
- NSS = unescapeNSS(RawNSS);
- return true;
-}
-
-URNResolver::URNResolver()
-{
-}
-
-QVariant URNResolver::resolve(QString URN)
-{
- QString NID, NSS;
- parse(URN, NID, NSS);
-
- if(NID != "x-mmc")
- return QVariant();
- auto parts = NSS.split(":");
- if(parts.size() < 1)
- return QVariant();
- unsigned int version = parts[0].toUInt();
- switch(version)
- {
- case 1:
- return resolveV1(parts.mid(1));
- default:
- return QVariant();
- }
-}
-
-/**
- * TODO: implement.
- */
-QVariant URNResolver::resolveV1(QStringList parts)
-{
- return QVariant();
-}
diff --git a/logic/URNResolver.h b/logic/URNResolver.h
deleted file mode 100644
index dfc7f5eb..00000000
--- a/logic/URNResolver.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-#include <QString>
-#include <QMap>
-#include <memory>
-#include <QVariant>
-
-class URNResolver;
-typedef std::shared_ptr<URNResolver> URNResolverPtr;
-
-class URNResolver
-{
-public:
- URNResolver();
- QVariant resolve (QString URN);
- static bool parse (const QString &URN, QString &NID, QString &NSS);
-private:
- QVariant resolveV1 (QStringList parts);
-};
diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp
index 311271fe..3e0648cc 100644
--- a/logic/minecraft/VersionFile.cpp
+++ b/logic/minecraft/VersionFile.cpp
@@ -43,6 +43,7 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi
}
if (!doc.isObject())
{
+ throw JSONValidationError(filename + " is not an object");
}
QJsonObject root = doc.object();