Ejemplo n.º 1
0
void LegacyUpdate::fmllibsFinished()
{
	legacyDownloadJob.reset();
	if(!fmlLibsToProcess.isEmpty())
	{
		setStatus(tr("Copying FML libraries into the instance..."));
		LegacyInstance *inst = (LegacyInstance *)m_inst;
		auto metacache = MMC->metacache();
		int index = 0;
		for (auto &lib : fmlLibsToProcess)
		{
			progress(index, fmlLibsToProcess.size());
			auto entry = metacache->resolveEntry("fmllibs", lib.name);
			auto path = PathCombine(inst->libDir(), lib.name);
			if(!ensureFilePathExists(path))
			{
				emitFailed(tr("Failed creating FML library folder inside the instance."));
				return;
			}
			if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.name)))
			{
				emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.name));
				return;
			}
			index++;
		}
		progress(index, fmlLibsToProcess.size());
	}
	lwjglStart();
}
Ejemplo n.º 2
0
void MainWindow::on_actionChangeInstLWJGLVersion_triggered()
{
	if (!m_selectedInstance)
		return;

	LWJGLSelectDialog lselect(this);
	lselect.exec();
	if (lselect.result() == QDialog::Accepted)
	{
		LegacyInstance *linst = (LegacyInstance *)m_selectedInstance;
		linst->setLWJGLVersion(lselect.selectedVersion());
	}
}
Ejemplo n.º 3
0
void MainWindow::on_actionEditInstNotes_triggered()
{
	if (!m_selectedInstance)
		return;
	LegacyInstance *linst = (LegacyInstance *)m_selectedInstance;

	EditNotesDialog noteedit(linst->notes(), linst->name(), this);
	noteedit.exec();
	if (noteedit.result() == QDialog::Accepted)
	{

		linst->setNotes(noteedit.getText());
	}
}
Ejemplo n.º 4
0
void LegacyUpdate::lwjglStart()
{
	LegacyInstance *inst = (LegacyInstance *)m_inst;

	lwjglVersion = inst->lwjglVersion();
	lwjglTargetPath = PathCombine(MMC->settings()->get("LWJGLDir").toString(), lwjglVersion);
	lwjglNativesPath = PathCombine(lwjglTargetPath, "natives");

	// if the 'done' file exists, we don't have to download this again
	QFileInfo doneFile(PathCombine(lwjglTargetPath, "done"));
	if (doneFile.exists())
	{
		jarStart();
		return;
	}

	auto list = MMC->lwjgllist();
	if (!list->isLoaded())
	{
		emitFailed("Too soon! Let the LWJGL list load :)");
		return;
	}

	setStatus(tr("Downloading new LWJGL..."));
	auto version = list->getVersion(lwjglVersion);
	if (!version)
	{
		emitFailed("Game update failed: the selected LWJGL version is invalid.");
		return;
	}

	QString url = version->url();
	QUrl realUrl(url);
	QString hostname = realUrl.host();
	auto worker = MMC->qnam();
	QNetworkRequest req(realUrl);
	req.setRawHeader("Host", hostname.toLatin1());
	req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
	QNetworkReply *rep = worker->get(req);

	m_reply = std::shared_ptr<QNetworkReply>(rep);
	connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
	connect(worker.get(), SIGNAL(finished(QNetworkReply *)),
			SLOT(lwjglFinished(QNetworkReply *)));
	// connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
	// SLOT(downloadError(QNetworkReply::NetworkError)));
}
Ejemplo n.º 5
0
void LegacyUpdate::jarStart()
{
	LegacyInstance *inst = (LegacyInstance *)m_inst;
	if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
	{
		ModTheJar();
		return;
	}

	setStatus(tr("Checking for jar updates..."));
	// Make directories
	QDir binDir(inst->binDir());
	if (!binDir.exists() && !binDir.mkpath("."))
	{
		emitFailed("Failed to create bin folder.");
		return;
	}

	// Build a list of URLs that will need to be downloaded.
	setStatus(tr("Downloading new minecraft.jar ..."));

	QString version_id = inst->intendedVersionId();
	QString localPath = version_id + "/" + version_id + ".jar";
	QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath;

	auto dljob = new NetJob("Minecraft.jar for version " + version_id);

	auto metacache = MMC->metacache();
	auto entry = metacache->resolveEntry("versions", localPath);
	dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
	connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
	connect(dljob, SIGNAL(failed()), SLOT(jarFailed()));
	connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
	legacyDownloadJob.reset(dljob);
	legacyDownloadJob->start();
}
Ejemplo n.º 6
0
void LegacyUpdate::ModTheJar()
{
	LegacyInstance *inst = (LegacyInstance *)m_inst;

	if (!inst->shouldRebuild())
	{
		emitSucceeded();
		return;
	}

	// Get the mod list
	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)
	{
		// 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;
	}

	// 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;
	}

	// Recompress the jar
	zipOut.close();
	if (zipOut.getZipError() != 0)
	{
		QFile::remove(runnableJar.filePath());
		emitFailed("Failed to finalize minecraft.jar!");
		return;
	}
	inst->setShouldRebuild(false);
	// inst->UpdateVersion(true);
	emitSucceeded();
	return;
}
Ejemplo n.º 7
0
void LegacyUpdate::fmllibsStart()
{
	// Get the mod list
	LegacyInstance *inst = (LegacyInstance *)m_inst;
	auto modList = inst->jarModList();

	bool forge_present = false;

	QString version = inst->intendedVersionId();
	if (!fmlLibsMapping.contains(version))
	{
		lwjglStart();
		return;
	}

	auto &libList = fmlLibsMapping[version];

	// determine if we need some libs for FML or forge
	setStatus(tr("Checking for FML libraries..."));
	for (unsigned i = 0; i < modList->size(); i++)
	{
		auto &mod = modList->operator[](i);

		// do not use disabled mods.
		if (!mod.enabled())
			continue;

		if (mod.type() != Mod::MOD_ZIPFILE)
			continue;

		if (mod.mmc_id().contains("forge", Qt::CaseInsensitive))
		{
			forge_present = true;
			break;
		}
		if (mod.mmc_id().contains("fml", Qt::CaseInsensitive))
		{
			forge_present = true;
			break;
		}
	}
	// we don't...
	if (!forge_present)
	{
		lwjglStart();
		return;
	}

	// now check the lib folder inside the instance for files.
	for (auto &lib : libList)
	{
		QFileInfo libInfo(PathCombine(inst->libDir(), lib.name));
		if (libInfo.exists())
			continue;
		fmlLibsToProcess.append(lib);
	}

	// if everything is in place, there's nothing to do here...
	if (fmlLibsToProcess.isEmpty())
	{
		lwjglStart();
		return;
	}

	// download missing libs to our place
	setStatus(tr("Dowloading FML libraries..."));
	auto dljob = new NetJob("FML libraries");
	auto metacache = MMC->metacache();
	for (auto &lib : fmlLibsToProcess)
	{
		auto entry = metacache->resolveEntry("fmllibs", lib.name);
		QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.name
									 : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.name;
		dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
	}

	connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished()));
	connect(dljob, SIGNAL(failed()), SLOT(fmllibsFailed()));
	connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
	legacyDownloadJob.reset(dljob);
	legacyDownloadJob->start();
}