Legacy jar reassembly, base of proper custom jar support
This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
				
			|||||||
#include "JlCompress.h"
 | 
					#include "JlCompress.h"
 | 
				
			||||||
#include <QDebug>
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool copyData(QIODevice &inFile, QIODevice &outFile)
 | 
					bool JlCompress::copyData(QIODevice &inFile, QIODevice &outFile)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    while (!inFile.atEnd()) {
 | 
					    while (!inFile.atEnd()) {
 | 
				
			||||||
        char buf[4096];
 | 
					        char buf[4096];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,8 @@ private:
 | 
				
			|||||||
    static bool removeFile(QStringList listFile);
 | 
					    static bool removeFile(QStringList listFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    /// copy data from inFile to outFile
 | 
				
			||||||
 | 
					    static bool copyData(QIODevice &inFile, QIODevice &outFile);
 | 
				
			||||||
    /// Compress a single file.
 | 
					    /// Compress a single file.
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
      \param fileCompressed The name of the archive.
 | 
					      \param fileCompressed The name of the archive.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,17 @@ LIBUTIL_EXPORT QString RemoveInvalidFilenameChars(QString string, QChar replaceW
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
LIBUTIL_EXPORT QString DirNameFromString(QString string, QString inDir = ".");
 | 
					LIBUTIL_EXPORT QString DirNameFromString(QString string, QString inDir = ".");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LIBUTIL_EXPORT bool ensurePathExists(QString filenamepath);
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates all the folders in a path for the specified path
 | 
				
			||||||
 | 
					 * last segment of the path is treated as a file name and is ignored!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					LIBUTIL_EXPORT bool ensureFilePathExists(QString filenamepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates all the folders in a path for the specified path
 | 
				
			||||||
 | 
					 * last segment of the path is treated as a folder name and is created!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					LIBUTIL_EXPORT bool ensureFolderPathExists(QString filenamepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LIBUTIL_EXPORT bool copyPath(QString src, QString dst);
 | 
					LIBUTIL_EXPORT bool copyPath(QString src, QString dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
#include <QDir>
 | 
					#include <QDir>
 | 
				
			||||||
#include <QDesktopServices>
 | 
					#include <QDesktopServices>
 | 
				
			||||||
#include <QUrl>
 | 
					#include <QUrl>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString PathCombine(QString path1, QString path2)
 | 
					QString PathCombine(QString path1, QString path2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -68,24 +69,38 @@ QString DirNameFromString(QString string, QString inDir)
 | 
				
			|||||||
	return dirName;
 | 
						return dirName;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ensurePathExists(QString filenamepath)
 | 
					bool ensureFilePathExists(QString filenamepath)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QFileInfo a ( filenamepath );
 | 
						QFileInfo a ( filenamepath );
 | 
				
			||||||
	QDir dir;
 | 
						QDir dir;
 | 
				
			||||||
	return (dir.mkpath ( a.filePath() ));
 | 
						QString ensuredPath = a.path();
 | 
				
			||||||
 | 
						bool success = dir.mkpath ( ensuredPath );
 | 
				
			||||||
 | 
						qDebug() << "ensureFilePathExists:" << success << ensuredPath << filenamepath;
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ensureFolderPathExists(QString foldernamepath)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						QFileInfo a ( foldernamepath );
 | 
				
			||||||
 | 
						QDir dir;
 | 
				
			||||||
 | 
						QString ensuredPath = a.filePath();
 | 
				
			||||||
 | 
						bool success = dir.mkpath ( ensuredPath );
 | 
				
			||||||
 | 
						qDebug() << "ensureFolderPathExists:" << success << ensuredPath << foldernamepath;
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool copyPath(QString src, QString dst)
 | 
					bool copyPath(QString src, QString dst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QDir dir(src);
 | 
						QDir dir(src);
 | 
				
			||||||
	if (!dir.exists())
 | 
						if (!dir.exists())
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	if(!ensurePathExists(dst))
 | 
						if(!ensureFolderPathExists(dst))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
 | 
						foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		QString inner_src = src+ QDir::separator() + d;
 | 
							QString inner_src = src + QDir::separator() + d;
 | 
				
			||||||
		QString inner_dst = dst + QDir::separator() + d;
 | 
							QString inner_dst = dst + QDir::separator() + d;
 | 
				
			||||||
		copyPath(inner_src, inner_dst);
 | 
							copyPath(inner_src, inner_dst);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,9 +28,9 @@ LegacyModEditDialog::LegacyModEditDialog( LegacyInstance* inst, QWidget* parent
 | 
				
			|||||||
	ui(new Ui::LegacyModEditDialog)
 | 
						ui(new Ui::LegacyModEditDialog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ui->setupUi(this);
 | 
						ui->setupUi(this);
 | 
				
			||||||
	ensurePathExists(m_inst->coreModsDir());
 | 
						ensureFolderPathExists(m_inst->coreModsDir());
 | 
				
			||||||
	ensurePathExists(m_inst->mlModsDir());
 | 
						ensureFolderPathExists(m_inst->mlModsDir());
 | 
				
			||||||
	ensurePathExists(m_inst->jarModsDir());
 | 
						ensureFolderPathExists(m_inst->jarModsDir());
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	m_mods = m_inst->loaderModList();
 | 
						m_mods = m_inst->loaderModList();
 | 
				
			||||||
	m_coremods = m_inst->coreModList();
 | 
						m_coremods = m_inst->coreModList();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,15 @@ BaseInstance::BaseInstance( BaseInstancePrivate* d_in,
 | 
				
			|||||||
	settings().registerSetting(new Setting("notes", ""));
 | 
						settings().registerSetting(new Setting("notes", ""));
 | 
				
			||||||
	settings().registerSetting(new Setting("lastLaunchTime", 0));
 | 
						settings().registerSetting(new Setting("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(new Setting("UseCustomBaseJar", true));
 | 
				
			||||||
 | 
						settings().registerSetting(new Setting("CustomBaseJar", ""));
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	// Java Settings
 | 
						// Java Settings
 | 
				
			||||||
	settings().registerSetting(new Setting("OverrideJava", false));
 | 
						settings().registerSetting(new Setting("OverrideJava", false));
 | 
				
			||||||
	settings().registerSetting(new OverrideSetting("JavaPath", globalSettings->getSetting("JavaPath")));
 | 
						settings().registerSetting(new OverrideSetting("JavaPath", globalSettings->getSetting("JavaPath")));
 | 
				
			||||||
@@ -121,6 +130,51 @@ SettingsObject &BaseInstance::settings() const
 | 
				
			|||||||
	return *d->m_settings;
 | 
						return *d->m_settings;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qint64 BaseInstance::lastLaunch() const
 | 
					qint64 BaseInstance::lastLaunch() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	I_D(BaseInstance);
 | 
						I_D(BaseInstance);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,6 +90,25 @@ public:
 | 
				
			|||||||
	virtual bool shouldUpdate() const = 0;
 | 
						virtual bool shouldUpdate() const = 0;
 | 
				
			||||||
	virtual void setShouldUpdate(bool val) = 0;
 | 
						virtual void setShouldUpdate(bool val) = 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.
 | 
						 * Gets the time that the instance was last launched.
 | 
				
			||||||
	 * Stored in milliseconds since epoch.
 | 
						 * Stored in milliseconds since epoch.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,8 @@ IconList::IconList() : QAbstractListModel(), d(new Private())
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// FIXME: get from settings
 | 
						// FIXME: get from settings
 | 
				
			||||||
	ensurePathExists("icons/");
 | 
						ensureFolderPathExists("icons");
 | 
				
			||||||
	QDir user_icons("icons/");
 | 
						QDir user_icons("icons");
 | 
				
			||||||
	file_info_list = user_icons.entryInfoList(QDir::Files, QDir::Name);
 | 
						file_info_list = user_icons.entryInfoList(QDir::Files, QDir::Name);
 | 
				
			||||||
	for(auto file_info: file_info_list)
 | 
						for(auto file_info: file_info_list)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,16 +90,19 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance( BaseInstance*&
 | 
				
			|||||||
			m_settings->set("InstanceType", "Legacy");
 | 
								m_settings->set("InstanceType", "Legacy");
 | 
				
			||||||
			inst = new LegacyInstance(instDir, m_settings, this);
 | 
								inst = new LegacyInstance(instDir, m_settings, this);
 | 
				
			||||||
			inst->setIntendedVersionId(version->descriptor);
 | 
								inst->setIntendedVersionId(version->descriptor);
 | 
				
			||||||
 | 
								inst->setShouldUseCustomBaseJar(false);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case MinecraftVersion::OneSix:
 | 
							case MinecraftVersion::OneSix:
 | 
				
			||||||
			m_settings->set("InstanceType", "OneSix");
 | 
								m_settings->set("InstanceType", "OneSix");
 | 
				
			||||||
			inst = new OneSixInstance(instDir, m_settings, this);
 | 
								inst = new OneSixInstance(instDir, m_settings, this);
 | 
				
			||||||
			inst->setIntendedVersionId(version->descriptor);
 | 
								inst->setIntendedVersionId(version->descriptor);
 | 
				
			||||||
 | 
								inst->setShouldUseCustomBaseJar(false);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case MinecraftVersion::Nostalgia:
 | 
							case MinecraftVersion::Nostalgia:
 | 
				
			||||||
			m_settings->set("InstanceType", "Nostalgia");
 | 
								m_settings->set("InstanceType", "Nostalgia");
 | 
				
			||||||
			inst = new NostalgiaInstance(instDir, m_settings, this);
 | 
								inst = new NostalgiaInstance(instDir, m_settings, this);
 | 
				
			||||||
			inst->setIntendedVersionId(version->descriptor);
 | 
								inst->setIntendedVersionId(version->descriptor);
 | 
				
			||||||
 | 
								inst->setShouldUseCustomBaseJar(false);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,30 +169,25 @@ QString LegacyInstance::resourceDir() const
 | 
				
			|||||||
	return PathCombine(minecraftRoot(), "resources");
 | 
						return PathCombine(minecraftRoot(), "resources");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString LegacyInstance::mcJar() const
 | 
					QString LegacyInstance::runnableJar() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return PathCombine(binDir(), "minecraft.jar");
 | 
						return PathCombine(binDir(), "minecraft.jar");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString LegacyInstance::mcBackup() const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return PathCombine(binDir(), "mcbackup.jar");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QString LegacyInstance::modListFile() const
 | 
					QString LegacyInstance::modListFile() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return PathCombine(instanceRoot(), "modlist");
 | 
						return PathCombine(instanceRoot(), "modlist");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
bool LegacyInstance::shouldUpdateCurrentVersion() const
 | 
					bool LegacyInstance::shouldUpdateCurrentVersion() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QFileInfo jar(mcJar());
 | 
						QFileInfo jar(runnableJar());
 | 
				
			||||||
	return jar.lastModified().toUTC().toMSecsSinceEpoch() != lastCurrentVersionUpdate();
 | 
						return jar.lastModified().toUTC().toMSecsSinceEpoch() != lastCurrentVersionUpdate();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LegacyInstance::updateCurrentVersion(bool keepCurrent)
 | 
					void LegacyInstance::updateCurrentVersion(bool keepCurrent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QFileInfo jar(mcJar());
 | 
						QFileInfo jar(runnableJar());
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if(!jar.exists())
 | 
						if(!jar.exists())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -221,6 +216,7 @@ void LegacyInstance::setLastCurrentVersionUpdate ( qint64 val )
 | 
				
			|||||||
	I_D(LegacyInstance);
 | 
						I_D(LegacyInstance);
 | 
				
			||||||
	d->m_settings->set ( "lastVersionUpdate", val );
 | 
						d->m_settings->set ( "lastVersionUpdate", val );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
bool LegacyInstance::shouldRebuild() const
 | 
					bool LegacyInstance::shouldRebuild() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	I_D(LegacyInstance);
 | 
						I_D(LegacyInstance);
 | 
				
			||||||
@@ -278,3 +274,14 @@ void LegacyInstance::setShouldUpdate ( bool val )
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	settings().set ( "ShouldUpdate", val );
 | 
						settings().set ( "ShouldUpdate", val );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString LegacyInstance::defaultBaseJar() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString LegacyInstance::defaultCustomBaseJar() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PathCombine(binDir(), "mcbackup.jar");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,10 +13,7 @@ public:
 | 
				
			|||||||
	explicit LegacyInstance(const QString &rootDir, SettingsObject * settings, QObject *parent = 0);
 | 
						explicit LegacyInstance(const QString &rootDir, SettingsObject * settings, QObject *parent = 0);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/// Path to the instance's minecraft.jar
 | 
						/// Path to the instance's minecraft.jar
 | 
				
			||||||
	QString mcJar() const;
 | 
						QString runnableJar() const;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	//! Path to the instance's mcbackup.jar
 | 
					 | 
				
			||||||
	QString mcBackup() const;
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	//! Path to the instance's modlist file.
 | 
						//! Path to the instance's modlist file.
 | 
				
			||||||
	QString modListFile() const;
 | 
						QString modListFile() const;
 | 
				
			||||||
@@ -34,35 +31,6 @@ public:
 | 
				
			|||||||
	QString coreModsDir() const;
 | 
						QString coreModsDir() const;
 | 
				
			||||||
	QString resourceDir() const;
 | 
						QString resourceDir() const;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/*!
 | 
					 | 
				
			||||||
	 * \brief Checks whether or not the currentVersion of the instance needs to be updated. 
 | 
					 | 
				
			||||||
	 *        If this returns true, updateCurrentVersion is called. In the 
 | 
					 | 
				
			||||||
	 *        standard instance, this is determined by checking a timestamp 
 | 
					 | 
				
			||||||
	 *        stored in the instance config file against the last modified time of Minecraft.jar.
 | 
					 | 
				
			||||||
	 * \return True if updateCurrentVersion() should be called.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	bool shouldUpdateCurrentVersion() const;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/*!
 | 
					 | 
				
			||||||
	 * \brief Updates the current version. 
 | 
					 | 
				
			||||||
	 *        This function should first set the current version timestamp 
 | 
					 | 
				
			||||||
	 *        (setCurrentVersionTimestamp()) to the current time. Next, if 
 | 
					 | 
				
			||||||
	 *        keepCurrent is false, this function should check what the 
 | 
					 | 
				
			||||||
	 *        instance's current version is and call setCurrentVersion() to 
 | 
					 | 
				
			||||||
	 *        update it. This function will automatically be called when the 
 | 
					 | 
				
			||||||
	 *        instance is loaded if shouldUpdateCurrentVersion returns true.
 | 
					 | 
				
			||||||
	 * \param keepCurrent If true, only the version timestamp will be updated.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void updateCurrentVersion(bool keepCurrent = false); 
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/*!
 | 
					 | 
				
			||||||
	 * Gets the last time that the current version was checked.
 | 
					 | 
				
			||||||
	 * This is checked against the last modified time on the jar file to see if
 | 
					 | 
				
			||||||
	 * the current version needs to be checked again.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	qint64 lastCurrentVersionUpdate() const;
 | 
					 | 
				
			||||||
	void setLastCurrentVersionUpdate(qint64 val);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/*!
 | 
						/*!
 | 
				
			||||||
	 * Whether or not the instance's minecraft.jar needs to be rebuilt.
 | 
						 * 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 
 | 
						 * If this is true, when the instance launches, its jar mods will be 
 | 
				
			||||||
@@ -90,6 +58,9 @@ public:
 | 
				
			|||||||
	virtual void cleanupAfterRun();
 | 
						virtual void cleanupAfterRun();
 | 
				
			||||||
	virtual QDialog * createModEditDialog ( QWidget* parent );
 | 
						virtual QDialog * createModEditDialog ( QWidget* parent );
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						virtual QString defaultBaseJar() const;
 | 
				
			||||||
 | 
						virtual QString defaultCustomBaseJar() const;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
protected slots:
 | 
					protected slots:
 | 
				
			||||||
	virtual void jarModsChanged();
 | 
						virtual void jarModsChanged();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -4,9 +4,11 @@
 | 
				
			|||||||
#include "BaseInstance.h"
 | 
					#include "BaseInstance.h"
 | 
				
			||||||
#include "LegacyInstance.h"
 | 
					#include "LegacyInstance.h"
 | 
				
			||||||
#include "net/NetWorker.h"
 | 
					#include "net/NetWorker.h"
 | 
				
			||||||
 | 
					#include "ModList.h"
 | 
				
			||||||
#include <pathutils.h>
 | 
					#include <pathutils.h>
 | 
				
			||||||
#include <quazip.h>
 | 
					#include <quazip.h>
 | 
				
			||||||
#include <quazipfile.h>
 | 
					#include <quazipfile.h>
 | 
				
			||||||
 | 
					#include <JlCompress.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LegacyUpdate::LegacyUpdate ( BaseInstance* inst, QObject* parent ) : BaseUpdate ( inst, parent ) {}
 | 
					LegacyUpdate::LegacyUpdate ( BaseInstance* inst, QObject* parent ) : BaseUpdate ( inst, parent ) {}
 | 
				
			||||||
@@ -22,7 +24,7 @@ void LegacyUpdate::lwjglStart()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	lwjglVersion =  inst->lwjglVersion();
 | 
						lwjglVersion =  inst->lwjglVersion();
 | 
				
			||||||
	lwjglTargetPath = PathCombine("lwjgl", lwjglVersion );
 | 
						lwjglTargetPath = PathCombine("lwjgl", lwjglVersion );
 | 
				
			||||||
	lwjglNativesPath = PathCombine( lwjglTargetPath, "natives/");
 | 
						lwjglNativesPath = PathCombine( lwjglTargetPath, "natives");
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// if the 'done' file exists, we don't have to download this again
 | 
						// if the 'done' file exists, we don't have to download this again
 | 
				
			||||||
	QFileInfo doneFile(PathCombine(lwjglTargetPath, "done"));
 | 
						QFileInfo doneFile(PathCombine(lwjglTargetPath, "done"));
 | 
				
			||||||
@@ -112,7 +114,7 @@ void LegacyUpdate::extractLwjgl()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	// make sure the directories are there
 | 
						// make sure the directories are there
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool success = ensurePathExists(lwjglNativesPath);
 | 
						bool success = ensureFolderPathExists(lwjglNativesPath);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if(!success)
 | 
						if(!success)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -201,33 +203,14 @@ void LegacyUpdate::lwjglFailed()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void LegacyUpdate::jarStart()
 | 
					void LegacyUpdate::jarStart()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setStatus("Checking ...");
 | 
					 | 
				
			||||||
	LegacyInstance * inst = (LegacyInstance *) m_inst;
 | 
						LegacyInstance * inst = (LegacyInstance *) m_inst;
 | 
				
			||||||
	QString current_version_id = inst->currentVersionId();
 | 
						if(!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
 | 
				
			||||||
	QString intended_version_id = inst->intendedVersionId();
 | 
					 | 
				
			||||||
	bool shouldUpdate = inst->shouldUpdate();
 | 
					 | 
				
			||||||
	if(!shouldUpdate)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		emitSucceeded();
 | 
							ModTheJar();
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// nuke the backup file, we are replacing the base jar anyway
 | 
					 | 
				
			||||||
	QFile mc_backup(inst->mcBackup());
 | 
					 | 
				
			||||||
	if (mc_backup.exists())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		mc_backup.remove();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// Get a pointer to the version object that corresponds to the instance's version.
 | 
					 | 
				
			||||||
	auto targetVersion = MinecraftVersionList::getMainList().findVersion(intended_version_id);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if(!targetVersion)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		emitFailed("Not a valid version:" + intended_version_id);
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						setStatus("Checking for jar updates...");
 | 
				
			||||||
	// Make directories
 | 
						// Make directories
 | 
				
			||||||
	QDir binDir(inst->binDir());
 | 
						QDir binDir(inst->binDir());
 | 
				
			||||||
	if (!binDir.exists() && !binDir.mkpath("."))
 | 
						if (!binDir.exists() && !binDir.mkpath("."))
 | 
				
			||||||
@@ -239,14 +222,11 @@ void LegacyUpdate::jarStart()
 | 
				
			|||||||
	// Build a list of URLs that will need to be downloaded.
 | 
						// Build a list of URLs that will need to be downloaded.
 | 
				
			||||||
	setStatus("Downloading new minecraft.jar");
 | 
						setStatus("Downloading new minecraft.jar");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// This will be either 'minecraft' or the version number, depending on where
 | 
					 | 
				
			||||||
	// we're downloading from.
 | 
					 | 
				
			||||||
	QString jarFilename = "minecraft";
 | 
					 | 
				
			||||||
	QString download_path = PathCombine(inst->minecraftRoot(), "bin/minecraft.jar");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
 | 
						QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
 | 
				
			||||||
	urlstr += targetVersion->descriptor + "/" + targetVersion->descriptor + ".jar";
 | 
						QString intended_version_id = inst->intendedVersionId();
 | 
				
			||||||
	auto dljob = DownloadJob::create(QUrl(urlstr), download_path);
 | 
						urlstr += intended_version_id + "/" + intended_version_id + ".jar";
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						auto dljob = DownloadJob::create(QUrl(urlstr), inst->defaultBaseJar());
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	legacyDownloadJob.reset(new JobList());
 | 
						legacyDownloadJob.reset(new JobList());
 | 
				
			||||||
	legacyDownloadJob->add(dljob);
 | 
						legacyDownloadJob->add(dljob);
 | 
				
			||||||
@@ -259,7 +239,7 @@ void LegacyUpdate::jarStart()
 | 
				
			|||||||
void LegacyUpdate::jarFinished()
 | 
					void LegacyUpdate::jarFinished()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// process the jar
 | 
						// process the jar
 | 
				
			||||||
	emitSucceeded();
 | 
						ModTheJar();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LegacyUpdate::jarFailed()
 | 
					void LegacyUpdate::jarFailed()
 | 
				
			||||||
@@ -268,74 +248,132 @@ void LegacyUpdate::jarFailed()
 | 
				
			|||||||
	emitFailed("Failed to download the minecraft jar. Try again later.");
 | 
						emitFailed("Failed to download the minecraft jar. Try again later.");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool LegacyUpdate::MergeZipFiles( QuaZip* into, QFileInfo from, QSet< QString >& contained )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						setStatus("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"))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if(contained.contains(filename))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							contained.insert(filename);
 | 
				
			||||||
 | 
							qDebug() << "Adding file " << filename << " from " << from.fileName();
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(!fileInsideMod.open(QIODevice::ReadOnly))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if(!zipOutFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileInsideMod.getActualFileName())))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								fileInsideMod.close();
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if(!JlCompress::copyData(fileInsideMod, zipOutFile))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								zipOutFile.close();
 | 
				
			||||||
 | 
								fileInsideMod.close();
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							zipOutFile.close();
 | 
				
			||||||
 | 
							fileInsideMod.close();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LegacyUpdate::ModTheJar()
 | 
					void LegacyUpdate::ModTheJar()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	LegacyInstance * inst = (LegacyInstance *) m_inst;
 | 
						LegacyInstance * inst = (LegacyInstance *) m_inst;
 | 
				
			||||||
	// Get the mod list
 | 
					 | 
				
			||||||
	auto modList = inst->getJarModList();
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	QFileInfo mcBin(inst->binDir());
 | 
						if(!inst->shouldRebuild())
 | 
				
			||||||
	QFileInfo mcJar(inst->mcJar());
 | 
					 | 
				
			||||||
	QFileInfo mcBackup(inst->mcBackup());
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// Nothing to do if there are no jar mods to install, no backup and just the mc jar
 | 
					 | 
				
			||||||
	if(mcJar.isFile() && !mcBackup.exists() && modList->empty())
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		inst->setShouldRebuild(false);
 | 
					 | 
				
			||||||
		emitSucceeded();
 | 
							emitSucceeded();
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	setStatus("Installing mods - backing up minecraft.jar...");
 | 
						// Get the mod list
 | 
				
			||||||
	if (!mcBackup.exists() && !QFile::copy(mcJar.absoluteFilePath(), mcBackup.absoluteFilePath()) )
 | 
						auto modList = inst->jarModList();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		emitFailed("Failed to back up minecraft.jar");
 | 
							// 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("Installing mods - backing up minecraft.jar...");
 | 
				
			||||||
 | 
							if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								emitFailed("Failed to back up minecraft.jar");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (!baseJar.exists())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							emitFailed("The base jar " + baseJar.filePath() + " does not exist");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (mcJar.isFile() && !QFile::remove(mcJar.absoluteFilePath()))
 | 
						if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		emitFailed("Failed to delete old minecraft.jar");
 | 
							emitFailed("Failed to delete old minecraft.jar");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						//TaskStep(); // STEP 1
 | 
				
			||||||
	setStatus("Installing mods - Opening minecraft.jar");
 | 
						setStatus("Installing mods - Opening minecraft.jar");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wxFFileOutputStream jarStream(mcJar.absoluteFilePath());
 | 
						QuaZip zipOut(runnableJar.filePath());
 | 
				
			||||||
	wxZipOutputStream zipOut(jarStream);
 | 
						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.
 | 
						// Files already added to the jar.
 | 
				
			||||||
	// These files will be skipped.
 | 
						// These files will be skipped.
 | 
				
			||||||
	QSet<QString> addedFiles;
 | 
						QSet<QString> addedFiles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Modify the jar
 | 
						// Modify the jar
 | 
				
			||||||
	setStatus("Installing mods - Adding mod files...");
 | 
						setStatus("Installing mods - Adding mod files...");
 | 
				
			||||||
	for (ModList::const_reverse_iterator iter = modList->rbegin(); iter != modList->rend(); iter++)
 | 
						for (int i = modList->size() - 1; i >= 0; i--)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		wxFileName modFileName = iter->GetFileName();
 | 
							auto &mod = modList->operator[](i);
 | 
				
			||||||
		setStatus("Installing mods - Adding " + modFileName.GetFullName());
 | 
							if (mod.type() == Mod::MOD_ZIPFILE)
 | 
				
			||||||
		if (iter->GetModType() == Mod::ModType::MOD_ZIPFILE)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			wxFFileInputStream modStream(modFileName.GetFullPath());
 | 
								if(!MergeZipFiles(&zipOut, mod.filename(), addedFiles))
 | 
				
			||||||
			wxZipInputStream zipStream(modStream);
 | 
					 | 
				
			||||||
			std::unique_ptr<wxZipEntry> entry;
 | 
					 | 
				
			||||||
			while (entry.reset(zipStream.GetNextEntry()), entry.get() != NULL)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (entry->IsDir())
 | 
									zipOut.close();
 | 
				
			||||||
					continue;
 | 
									QFile::remove(runnableJar.filePath());
 | 
				
			||||||
 | 
									emitFailed("Failed to add " + mod.filename().fileName() + " to the jar.");
 | 
				
			||||||
				wxString name = entry->GetName();
 | 
									return;
 | 
				
			||||||
				if (addedFiles.count(name) == 0)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (!zipOut.CopyEntry(entry.release(), zipStream))
 | 
					 | 
				
			||||||
						break;
 | 
					 | 
				
			||||||
					addedFiles.insert(name);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else if (mod.type() == Mod::MOD_SINGLEFILE)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								zipOut.close();
 | 
				
			||||||
 | 
								QFile::remove(runnableJar.filePath());
 | 
				
			||||||
 | 
								emitFailed("Loose files are NOT supported as jar mods.");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
			wxFileName destFileName = modFileName;
 | 
								wxFileName destFileName = modFileName;
 | 
				
			||||||
			destFileName.MakeRelativeTo(m_inst->GetInstModsDir().GetFullPath());
 | 
								destFileName.MakeRelativeTo(m_inst->GetInstModsDir().GetFullPath());
 | 
				
			||||||
			wxString destFile = destFileName.GetFullPath();
 | 
								wxString destFile = destFileName.GetFullPath();
 | 
				
			||||||
@@ -348,34 +386,35 @@ void LegacyUpdate::ModTheJar()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				addedFiles.insert(destFile);
 | 
									addedFiles.insert(destFile);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								*/
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (mod.type() == Mod::MOD_FOLDER)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								zipOut.close();
 | 
				
			||||||
 | 
								QFile::remove(runnableJar.filePath());
 | 
				
			||||||
 | 
								emitFailed("Folders are NOT supported as jar mods.");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						if(!MergeZipFiles(&zipOut, baseJar, addedFiles))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		wxFFileInputStream inStream(mcBackup.GetFullPath());
 | 
							zipOut.close();
 | 
				
			||||||
		wxZipInputStream zipIn(inStream);
 | 
							QFile::remove(runnableJar.filePath());
 | 
				
			||||||
 | 
							emitFailed("Failed to insert minecraft.jar contents.");
 | 
				
			||||||
		std::auto_ptr<wxZipEntry> entry;
 | 
							return;
 | 
				
			||||||
		while (entry.reset(zipIn.GetNextEntry()), entry.get() != NULL)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			wxString name = entry->GetName();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!name.Matches("META-INF*") &&
 | 
					 | 
				
			||||||
				addedFiles.count(name) == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (!zipOut.CopyEntry(entry.release(), zipIn))
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				addedFiles.insert(name);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// Recompress the jar
 | 
						// Recompress the jar
 | 
				
			||||||
	TaskStep(); // STEP 3
 | 
						zipOut.close();
 | 
				
			||||||
	SetStatus(_("Installing mods - Recompressing jar..."));
 | 
					    if(zipOut.getZipError()!=0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
	inst->SetNeedsRebuild(false);
 | 
							QFile::remove(runnableJar.filePath());
 | 
				
			||||||
	inst->UpdateVersion(true);
 | 
							emitFailed("Failed to finalize minecraft.jar!");
 | 
				
			||||||
	return (ExitCode)1;
 | 
							return;
 | 
				
			||||||
	*/
 | 
					    }
 | 
				
			||||||
 | 
						inst->setShouldRebuild(false);
 | 
				
			||||||
 | 
						//inst->UpdateVersion(true);
 | 
				
			||||||
 | 
						emitSucceeded();
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -25,6 +25,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class MinecraftVersion;
 | 
					class MinecraftVersion;
 | 
				
			||||||
class BaseInstance;
 | 
					class BaseInstance;
 | 
				
			||||||
 | 
					class QuaZip;
 | 
				
			||||||
 | 
					class Mod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LegacyUpdate : public BaseUpdate
 | 
					class LegacyUpdate : public BaseUpdate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -46,6 +48,8 @@ private slots:
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	void ModTheJar();
 | 
						void ModTheJar();
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
						bool MergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString>& contained);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	QSharedPointer<QNetworkReply> m_reply;
 | 
						QSharedPointer<QNetworkReply> m_reply;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@@ -59,9 +63,6 @@ private:
 | 
				
			|||||||
private:
 | 
					private:
 | 
				
			||||||
	JobListPtr legacyDownloadJob;
 | 
						JobListPtr legacyDownloadJob;
 | 
				
			||||||
	JobListQueue download_queue;
 | 
						JobListQueue download_queue;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// target version, determined during this task
 | 
					 | 
				
			||||||
	QSharedPointer<MinecraftVersion> targetVersion;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ public:
 | 
				
			|||||||
	virtual int columnCount ( const QModelIndex& parent ) const;
 | 
						virtual int columnCount ( const QModelIndex& parent ) const;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	size_t size() const { return mods.size(); };
 | 
						size_t size() const { return mods.size(); };
 | 
				
			||||||
 | 
						bool empty() const { return size() == 0; }
 | 
				
			||||||
	Mod& operator[](size_t index) { return mods[index]; };
 | 
						Mod& operator[](size_t index) { return mods[index]; };
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/// Reloads the mod list and returns true if the list changed.
 | 
						/// Reloads the mod list and returns true if the list changed.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,7 +92,7 @@ MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString sessi
 | 
				
			|||||||
		return nullptr;
 | 
							return nullptr;
 | 
				
			||||||
	auto libs_to_extract = version->getActiveNativeLibs();
 | 
						auto libs_to_extract = version->getActiveNativeLibs();
 | 
				
			||||||
	QString natives_dir_raw = PathCombine(instanceRoot(), "natives/");
 | 
						QString natives_dir_raw = PathCombine(instanceRoot(), "natives/");
 | 
				
			||||||
	bool success = ensurePathExists(natives_dir_raw);
 | 
						bool success = ensureFolderPathExists(natives_dir_raw);
 | 
				
			||||||
	if(!success)
 | 
						if(!success)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// FIXME: handle errors
 | 
							// FIXME: handle errors
 | 
				
			||||||
@@ -216,3 +216,13 @@ QSharedPointer< FullVersion > OneSixInstance::getFullVersion()
 | 
				
			|||||||
	I_D(OneSixInstance);
 | 
						I_D(OneSixInstance);
 | 
				
			||||||
	return d->version;
 | 
						return d->version;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString OneSixInstance::defaultBaseJar() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString OneSixInstance::defaultCustomBaseJar() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PathCombine(instanceRoot(), "custom.jar");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,9 @@ public:
 | 
				
			|||||||
	bool reloadFullVersion();
 | 
						bool reloadFullVersion();
 | 
				
			||||||
	/// get the current full version info
 | 
						/// get the current full version info
 | 
				
			||||||
	QSharedPointer<FullVersion> getFullVersion();
 | 
						QSharedPointer<FullVersion> getFullVersion();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						virtual QString defaultBaseJar() const;
 | 
				
			||||||
 | 
						virtual QString defaultCustomBaseJar() const;
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	QStringList processMinecraftArgs( QString user, QString session );
 | 
						QStringList processMinecraftArgs( QString user, QString session );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -91,7 +91,7 @@ void OneSixUpdate::versionFileFinished()
 | 
				
			|||||||
	// save the version file in $instanceId/version.json
 | 
						// save the version file in $instanceId/version.json
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		QString version1 =  PathCombine(inst_dir, "/version.json");
 | 
							QString version1 =  PathCombine(inst_dir, "/version.json");
 | 
				
			||||||
		ensurePathExists(version1);
 | 
							ensureFilePathExists(version1);
 | 
				
			||||||
		// FIXME: detect errors here, download to a temp file, swap
 | 
							// FIXME: detect errors here, download to a temp file, swap
 | 
				
			||||||
		QFile  vfile1 (version1);
 | 
							QFile  vfile1 (version1);
 | 
				
			||||||
		vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly );
 | 
							vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ void DownloadJob::start()
 | 
				
			|||||||
				m_expected_md5 = hash;
 | 
									m_expected_md5 = hash;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(!ensurePathExists(filename))
 | 
							if(!ensureFilePathExists(filename))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			emit fail();
 | 
								emit fail();
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user