mirror of
https://github.com/MultiMC/MultiMC5.git
synced 2024-09-02 21:19:25 +00:00
GH-1034 do jar modding separate from update
This commit is contained in:
parent
5133b0f34f
commit
5dd48e89f5
@ -141,8 +141,8 @@ SET(MULTIMC_SOURCES
|
||||
SettingsUI.cpp
|
||||
|
||||
# Processes
|
||||
LaunchController.h
|
||||
LaunchController.cpp
|
||||
LaunchInteraction.h
|
||||
LaunchInteraction.cpp
|
||||
|
||||
# page provider for instances
|
||||
InstancePageProvider.h
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "LaunchController.h"
|
||||
#include "LaunchInteraction.h"
|
||||
#include <auth/MojangAccountList.h>
|
||||
#include "MultiMC.h"
|
||||
#include "dialogs/CustomMessageBox.h"
|
||||
@ -23,6 +23,7 @@ void LaunchController::launch()
|
||||
login();
|
||||
}
|
||||
|
||||
// FIXME: minecraft specific
|
||||
void LaunchController::login()
|
||||
{
|
||||
if (!m_instance)
|
||||
@ -156,7 +157,7 @@ void LaunchController::launchInstance()
|
||||
return;
|
||||
}
|
||||
|
||||
m_launcher = m_instance->prepareForLaunch(m_session);
|
||||
m_launcher = m_instance->createLaunchTask(m_session);
|
||||
if (!m_launcher)
|
||||
{
|
||||
return;
|
@ -372,7 +372,7 @@ namespace Ui {
|
||||
#include "java/JavaUtils.h"
|
||||
#include "JavaCommon.h"
|
||||
#include "InstancePageProvider.h"
|
||||
#include "LaunchController.h"
|
||||
#include "LaunchInteraction.h"
|
||||
#include "SettingsUI.h"
|
||||
#include "minecraft/SkinUtils.h"
|
||||
#include "resources/Resource.h"
|
||||
@ -1184,7 +1184,7 @@ void MainWindow::finalizeInstance(InstancePtr inst)
|
||||
if (MMC->accounts()->anyAccountIsValid())
|
||||
{
|
||||
ProgressDialog loadDialog(this);
|
||||
auto update = inst->doUpdate();
|
||||
auto update = inst->createUpdateTask();
|
||||
connect(update.get(), &Task::failed, [this](QString reason)
|
||||
{
|
||||
QString error = QString("Instance load failed: %1").arg(reason);
|
||||
|
@ -269,7 +269,7 @@ void VersionPage::on_changeVersionBtn_clicked()
|
||||
|
||||
int VersionPage::doUpdate()
|
||||
{
|
||||
auto updateTask = m_inst->doUpdate();
|
||||
auto updateTask = m_inst->createUpdateTask();
|
||||
if (!updateTask)
|
||||
{
|
||||
return 1;
|
||||
|
@ -135,13 +135,21 @@ public:
|
||||
virtual SettingsObjectPtr settings() const;
|
||||
|
||||
/// returns a valid update task
|
||||
virtual std::shared_ptr<Task> doUpdate() = 0;
|
||||
virtual std::shared_ptr<Task> createUpdateTask() = 0;
|
||||
|
||||
/// returns a valid process, ready for launch with the given account.
|
||||
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) = 0;
|
||||
/// returns a valid launcher (task container)
|
||||
virtual std::shared_ptr<BaseLauncher> createLaunchTask(AuthSessionPtr account) = 0;
|
||||
|
||||
/// do any necessary cleanups after the instance finishes. also runs before
|
||||
/// 'prepareForLaunch'
|
||||
/*!
|
||||
* Returns a task that should be done right before launch
|
||||
* This task should do any extra preparations needed
|
||||
*/
|
||||
virtual std::shared_ptr<Task> createJarModdingTask() = 0;
|
||||
|
||||
/*!
|
||||
* does any necessary cleanups after the instance finishes. also runs before\
|
||||
* TODO: turn into a task that can run asynchronously
|
||||
*/
|
||||
virtual void cleanupAfterRun() = 0;
|
||||
|
||||
virtual QString getStatusbarDescription() = 0;
|
||||
|
@ -421,7 +421,7 @@ void BaseLauncher::on_pre_state(LoggedProcess::State state)
|
||||
|
||||
void BaseLauncher::updateInstance()
|
||||
{
|
||||
m_updateTask = m_instance->doUpdate();
|
||||
m_updateTask = m_instance->createUpdateTask();
|
||||
if(m_updateTask)
|
||||
{
|
||||
connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished()));
|
||||
@ -435,7 +435,7 @@ void BaseLauncher::updateFinished()
|
||||
{
|
||||
if(m_updateTask->successful())
|
||||
{
|
||||
makeReady();
|
||||
doJarModding();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -445,6 +445,28 @@ void BaseLauncher::updateFinished()
|
||||
}
|
||||
}
|
||||
|
||||
void BaseLauncher::doJarModding()
|
||||
{
|
||||
m_jarModTask = m_instance->createJarModdingTask();
|
||||
if(!m_jarModTask)
|
||||
{
|
||||
jarModdingSucceeded();
|
||||
}
|
||||
connect(m_jarModTask.get(), SIGNAL(succeeded()), this, SLOT(jarModdingSucceeded()));
|
||||
connect(m_jarModTask.get(), SIGNAL(failed(QString)), this, SLOT(jarModdingFailed(QString)));
|
||||
m_jarModTask->start();
|
||||
}
|
||||
|
||||
void BaseLauncher::jarModdingSucceeded()
|
||||
{
|
||||
makeReady();
|
||||
}
|
||||
|
||||
void BaseLauncher::jarModdingFailed(QString reason)
|
||||
{
|
||||
emitFailed(reason);
|
||||
}
|
||||
|
||||
void BaseLauncher::makeReady()
|
||||
{
|
||||
QStringList args = javaArguments();
|
||||
|
@ -95,6 +95,7 @@ public: /* HACK: MINECRAFT: split! */
|
||||
protected: /* methods */
|
||||
void preLaunch();
|
||||
void updateInstance();
|
||||
void doJarModding();
|
||||
void makeReady();
|
||||
void postLaunch();
|
||||
virtual void emitFailed(QString reason);
|
||||
@ -108,6 +109,10 @@ protected: /* methods */
|
||||
virtual QString censorPrivateInfo(QString in);
|
||||
virtual MessageLevel::Enum guessLevel(const QString &message, MessageLevel::Enum defaultLevel);
|
||||
|
||||
protected slots:
|
||||
void jarModdingSucceeded();
|
||||
void jarModdingFailed(QString reason);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief emitted when the launch preparations are done
|
||||
@ -161,6 +166,7 @@ protected: /* HACK: MINECRAFT: split! */
|
||||
QString launchScript;
|
||||
QString m_nativeFolder;
|
||||
std::shared_ptr<Task> m_updateTask;
|
||||
std::shared_ptr<Task> m_jarModTask;
|
||||
|
||||
protected: /* HACK: MINECRAFT: split! */
|
||||
void checkJava();
|
||||
|
@ -43,11 +43,15 @@ public:
|
||||
{
|
||||
return instanceRoot();
|
||||
};
|
||||
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr)
|
||||
virtual std::shared_ptr<BaseLauncher> createLaunchTask(AuthSessionPtr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual std::shared_ptr< Task > doUpdate()
|
||||
virtual std::shared_ptr< Task > createUpdateTask()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual std::shared_ptr<Task> createJarModdingTask()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -134,9 +134,9 @@ QString OneSixFTBInstance::getStatusbarDescription()
|
||||
return "OneSix FTB: " + intendedVersionId();
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> OneSixFTBInstance::doUpdate()
|
||||
std::shared_ptr<Task> OneSixFTBInstance::createUpdateTask()
|
||||
{
|
||||
return OneSixInstance::doUpdate();
|
||||
return OneSixInstance::createUpdateTask();
|
||||
}
|
||||
|
||||
#include "OneSixFTBInstance.moc"
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
virtual QString getStatusbarDescription();
|
||||
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
virtual std::shared_ptr<Task> createUpdateTask() override;
|
||||
|
||||
virtual QString id() const;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "icons/IconList.h"
|
||||
#include "BaseLauncher.h"
|
||||
#include "minecraft/ModList.h"
|
||||
#include <MMCZip.h>
|
||||
|
||||
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
|
||||
: MinecraftInstance(globalSettings, settings, rootDir)
|
||||
@ -87,7 +88,7 @@ bool LegacyInstance::shouldUseCustomBaseJar() const
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Task> LegacyInstance::doUpdate()
|
||||
std::shared_ptr<Task> LegacyInstance::createUpdateTask()
|
||||
{
|
||||
// make sure the jar mods list is initialized by asking for it.
|
||||
auto list = jarModList();
|
||||
@ -95,7 +96,7 @@ std::shared_ptr<Task> LegacyInstance::doUpdate()
|
||||
return std::shared_ptr<Task>(new LegacyUpdate(this, this));
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseLauncher> LegacyInstance::prepareForLaunch(AuthSessionPtr account)
|
||||
std::shared_ptr<BaseLauncher> LegacyInstance::createLaunchTask(AuthSessionPtr account)
|
||||
{
|
||||
QString launchScript;
|
||||
QIcon icon = ENV.icons()->getIcon(iconKey());
|
||||
@ -129,6 +130,87 @@ std::shared_ptr<BaseLauncher> LegacyInstance::prepareForLaunch(AuthSessionPtr ac
|
||||
return process;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
|
||||
{
|
||||
class JarModTask : public Task
|
||||
{
|
||||
public:
|
||||
explicit JarModTask(std::shared_ptr<LegacyInstance> inst) : m_inst(inst), Task(nullptr)
|
||||
{
|
||||
}
|
||||
virtual void executeTask()
|
||||
{
|
||||
if (!m_inst->shouldRebuild())
|
||||
{
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the mod list
|
||||
auto modList = m_inst->getJarMods();
|
||||
|
||||
QFileInfo runnableJar(m_inst->runnableJar());
|
||||
QFileInfo baseJar(m_inst->baseJar());
|
||||
bool base_is_custom = m_inst->shouldUseCustomBaseJar();
|
||||
|
||||
// Nothing to do if there are no jar mods to install, no backup and just the mc jar
|
||||
if (base_is_custom)
|
||||
{
|
||||
// yes, this can happen if the instance only has the runnable jar and not the base jar
|
||||
// it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
|
||||
// because that's not something mmc4 guarantees
|
||||
if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
|
||||
{
|
||||
m_inst->setShouldRebuild(false);
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
|
||||
if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
|
||||
{
|
||||
emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
|
||||
"be used on next run.");
|
||||
m_inst->setShouldRebuild(true);
|
||||
m_inst->setShouldUpdate(true);
|
||||
m_inst->setShouldUseCustomBaseJar(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!baseJar.exists())
|
||||
{
|
||||
emitFailed("The base jar " + baseJar.filePath() + " does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
|
||||
{
|
||||
emitFailed("Failed to delete old minecraft.jar");
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(tr("Installing mods: Opening minecraft.jar ..."));
|
||||
|
||||
QString outputJarPath = runnableJar.filePath();
|
||||
QString inputJarPath = baseJar.filePath();
|
||||
|
||||
if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
|
||||
{
|
||||
emitFailed(tr("Failed to create the custom Minecraft jar file."));
|
||||
return;
|
||||
}
|
||||
m_inst->setShouldRebuild(false);
|
||||
// inst->UpdateVersion(true);
|
||||
emitSucceeded();
|
||||
return;
|
||||
|
||||
}
|
||||
std::shared_ptr<LegacyInstance> m_inst;
|
||||
};
|
||||
return std::make_shared<JarModTask>(std::dynamic_pointer_cast<LegacyInstance>(shared_from_this()));
|
||||
}
|
||||
|
||||
void LegacyInstance::cleanupAfterRun()
|
||||
{
|
||||
// FIXME: delete the launcher and icons and whatnot.
|
||||
|
@ -109,9 +109,12 @@ public:
|
||||
|
||||
virtual bool shouldUpdate() const override;
|
||||
virtual void setShouldUpdate(bool val) override;
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
virtual std::shared_ptr<Task> createUpdateTask() override;
|
||||
|
||||
virtual std::shared_ptr<BaseLauncher> createLaunchTask(AuthSessionPtr account) override;
|
||||
|
||||
virtual std::shared_ptr<Task> createJarModdingTask() override;
|
||||
|
||||
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) override;
|
||||
virtual void cleanupAfterRun() override;
|
||||
|
||||
virtual QString getStatusbarDescription() override;
|
||||
|
@ -349,7 +349,7 @@ void LegacyUpdate::jarStart()
|
||||
LegacyInstance *inst = (LegacyInstance *)m_inst;
|
||||
if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
|
||||
{
|
||||
ModTheJar();
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -384,7 +384,7 @@ void LegacyUpdate::jarStart()
|
||||
void LegacyUpdate::jarFinished()
|
||||
{
|
||||
// process the jar
|
||||
ModTheJar();
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
void LegacyUpdate::jarFailed(QString reason)
|
||||
@ -392,73 +392,3 @@ void LegacyUpdate::jarFailed(QString reason)
|
||||
// bad, bad
|
||||
emitFailed(tr("Failed to download the minecraft jar: %1.").arg(reason));
|
||||
}
|
||||
|
||||
void LegacyUpdate::ModTheJar()
|
||||
{
|
||||
LegacyInstance *inst = (LegacyInstance *)m_inst;
|
||||
|
||||
if (!inst->shouldRebuild())
|
||||
{
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the mod list
|
||||
auto modList = inst->getJarMods();
|
||||
|
||||
QFileInfo runnableJar(inst->runnableJar());
|
||||
QFileInfo baseJar(inst->baseJar());
|
||||
bool base_is_custom = inst->shouldUseCustomBaseJar();
|
||||
|
||||
// Nothing to do if there are no jar mods to install, no backup and just the mc jar
|
||||
if (base_is_custom)
|
||||
{
|
||||
// yes, this can happen if the instance only has the runnable jar and not the base jar
|
||||
// it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
|
||||
// because that's not something mmc4 guarantees
|
||||
if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
|
||||
{
|
||||
inst->setShouldRebuild(false);
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
|
||||
if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
|
||||
{
|
||||
emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
|
||||
"be used on next run.");
|
||||
inst->setShouldRebuild(true);
|
||||
inst->setShouldUpdate(true);
|
||||
inst->setShouldUseCustomBaseJar(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!baseJar.exists())
|
||||
{
|
||||
emitFailed("The base jar " + baseJar.filePath() + " does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
|
||||
{
|
||||
emitFailed("Failed to delete old minecraft.jar");
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(tr("Installing mods: Opening minecraft.jar ..."));
|
||||
|
||||
QString outputJarPath = runnableJar.filePath();
|
||||
QString inputJarPath = baseJar.filePath();
|
||||
|
||||
if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
|
||||
{
|
||||
emitFailed(tr("Failed to create the custom Minecraft jar file."));
|
||||
return;
|
||||
}
|
||||
inst->setShouldRebuild(false);
|
||||
// inst->UpdateVersion(true);
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
@ -51,8 +51,6 @@ slots:
|
||||
|
||||
void extractLwjgl();
|
||||
|
||||
void ModTheJar();
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<QNetworkReply> m_reply;
|
||||
|
@ -56,7 +56,7 @@ QSet<QString> OneSixInstance::traits()
|
||||
return version->traits;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> OneSixInstance::doUpdate()
|
||||
std::shared_ptr<Task> OneSixInstance::createUpdateTask()
|
||||
{
|
||||
return std::shared_ptr<Task>(new OneSixUpdate(this));
|
||||
}
|
||||
@ -123,7 +123,7 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
|
||||
return parts;
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseLauncher> OneSixInstance::prepareForLaunch(AuthSessionPtr session)
|
||||
std::shared_ptr<BaseLauncher> OneSixInstance::createLaunchTask(AuthSessionPtr session)
|
||||
{
|
||||
QString launchScript;
|
||||
QIcon icon = ENV.icons()->getIcon(iconKey());
|
||||
@ -237,6 +237,64 @@ std::shared_ptr<BaseLauncher> OneSixInstance::prepareForLaunch(AuthSessionPtr se
|
||||
return process;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
|
||||
{
|
||||
class JarModTask : public Task
|
||||
{
|
||||
public:
|
||||
explicit JarModTask(std::shared_ptr<OneSixInstance> inst) : m_inst(inst), Task(nullptr)
|
||||
{
|
||||
}
|
||||
virtual void executeTask()
|
||||
{
|
||||
std::shared_ptr<MinecraftProfile> version = m_inst->getMinecraftProfile();
|
||||
// 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 tempJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
|
||||
QFile tempJar(tempJarPath);
|
||||
if(tempJar.exists())
|
||||
{
|
||||
tempJar.remove();
|
||||
}
|
||||
auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("minecraft.jar");
|
||||
QFile finalJar(finalJarPath);
|
||||
if(finalJar.exists())
|
||||
{
|
||||
if(!finalJar.remove())
|
||||
{
|
||||
emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// create temporary modded jar, if needed
|
||||
auto jarMods = m_inst->getJarMods();
|
||||
if(jarMods.size())
|
||||
{
|
||||
auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar");
|
||||
QString localPath = version_id + "/" + version_id + ".jar";
|
||||
auto metacache = ENV.metacache();
|
||||
auto entry = metacache->resolveEntry("versions", localPath);
|
||||
QString fullJarPath = entry->getFullPath();
|
||||
if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
|
||||
{
|
||||
emitFailed(tr("Failed to create the custom Minecraft jar file."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
emitSucceeded();
|
||||
}
|
||||
std::shared_ptr<OneSixInstance> m_inst;
|
||||
};
|
||||
return std::make_shared<JarModTask>(std::dynamic_pointer_cast<OneSixInstance>(shared_from_this()));
|
||||
}
|
||||
|
||||
void OneSixInstance::cleanupAfterRun()
|
||||
{
|
||||
QString target_dir = PathCombine(instanceRoot(), "natives/");
|
||||
|
@ -48,8 +48,9 @@ public:
|
||||
QString libDir() const;
|
||||
virtual QString instanceConfigFolder() const override;
|
||||
|
||||
virtual std::shared_ptr<Task> doUpdate() override;
|
||||
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) override;
|
||||
virtual std::shared_ptr<Task> createUpdateTask() override;
|
||||
virtual std::shared_ptr<BaseLauncher> createLaunchTask(AuthSessionPtr account) override;
|
||||
virtual std::shared_ptr<Task> createJarModdingTask() override;
|
||||
|
||||
virtual void cleanupAfterRun() override;
|
||||
|
||||
|
@ -296,46 +296,6 @@ void OneSixUpdate::jarlibFinished()
|
||||
OneSixInstance *inst = (OneSixInstance *)m_inst;
|
||||
std::shared_ptr<MinecraftProfile> version = inst->getMinecraftProfile();
|
||||
|
||||
// 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 tempJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
|
||||
QFile tempJar(tempJarPath);
|
||||
if(tempJar.exists())
|
||||
{
|
||||
tempJar.remove();
|
||||
}
|
||||
auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("minecraft.jar");
|
||||
QFile finalJar(finalJarPath);
|
||||
if(finalJar.exists())
|
||||
{
|
||||
if(!finalJar.remove())
|
||||
{
|
||||
emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// create temporary modded jar, if needed
|
||||
auto jarMods = inst->getJarMods();
|
||||
if(jarMods.size())
|
||||
{
|
||||
auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar");
|
||||
QString localPath = version_id + "/" + version_id + ".jar";
|
||||
auto metacache = ENV.metacache();
|
||||
auto entry = metacache->resolveEntry("versions", localPath);
|
||||
QString fullJarPath = entry->getFullPath();
|
||||
if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
|
||||
{
|
||||
emitFailed(tr("Failed to create the custom Minecraft jar file."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (version->traits.contains("legacyFML"))
|
||||
{
|
||||
fmllibsStart();
|
||||
|
Loading…
Reference in New Issue
Block a user