コード例 #1
0
ファイル: LegacyUpdate.cpp プロジェクト: Nightreaver/MultiMC5
void LegacyUpdate::lwjglFailed()
{
	emitFailed("Bad stuff happened while trying to get the lwjgl libs...");
}
コード例 #2
0
ファイル: LegacyUpdate.cpp プロジェクト: Nightreaver/MultiMC5
void LegacyUpdate::jarFailed()
{
	// bad, bad
	emitFailed("Failed to download the minecraft jar. Try again later.");
}
コード例 #3
0
ファイル: LegacyUpdate.cpp プロジェクト: Nightreaver/MultiMC5
void LegacyUpdate::fmllibsFailed()
{
	emitFailed("Game update failed: it was impossible to fetch the required FML libraries.");
	return;
}
コード例 #4
0
ファイル: LegacyUpdate.cpp プロジェクト: Nightreaver/MultiMC5
void LegacyUpdate::extractLwjgl()
{
	// make sure the directories are there

	bool success = ensureFolderPathExists(lwjglNativesPath);

	if (!success)
	{
		emitFailed("Failed to extract the lwjgl libs - error when creating required folders.");
		return;
	}

	QuaZip zip("lwjgl.zip");
	if (!zip.open(QuaZip::mdUnzip))
	{
		emitFailed("Failed to extract the lwjgl libs - not a valid archive.");
		return;
	}

	// and now we are going to access files inside it
	QuaZipFile file(&zip);
	const QString jarNames[] = {"jinput.jar", "lwjgl_util.jar", "lwjgl.jar"};
	for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
	{
		if (!file.open(QIODevice::ReadOnly))
		{
			zip.close();
			emitFailed("Failed to extract the lwjgl libs - error while reading archive.");
			return;
		}
		QuaZipFileInfo info;
		QString name = file.getActualFileName();
		if (name.endsWith('/'))
		{
			file.close();
			continue;
		}
		QString destFileName;
		// Look for the jars
		for (int i = 0; i < 3; i++)
		{
			if (name.endsWith(jarNames[i]))
			{
				destFileName = PathCombine(lwjglTargetPath, jarNames[i]);
			}
		}
		// Not found? look for the natives
		if (destFileName.isEmpty())
		{
#ifdef Q_OS_WIN32
			QString nativesDir = "windows";
#else
#ifdef Q_OS_MAC
			QString nativesDir = "macosx";
#else
			QString nativesDir = "linux";
#endif
#endif
			if (name.contains(nativesDir))
			{
				int lastSlash = name.lastIndexOf('/');
				int lastBackSlash = name.lastIndexOf('\\');
				if (lastSlash != -1)
					name = name.mid(lastSlash + 1);
				else if (lastBackSlash != -1)
					name = name.mid(lastBackSlash + 1);
				destFileName = PathCombine(lwjglNativesPath, name);
			}
		}
		// Now if destFileName is still empty, go to the next file.
		if (!destFileName.isEmpty())
		{
			setStatus(tr("Installing new LWJGL - extracting ") + name + "...");
			QFile output(destFileName);
			output.open(QIODevice::WriteOnly);
			output.write(file.readAll()); // FIXME: wste of memory!?
			output.close();
		}
		file.close(); // do not forget to close!
	}
	zip.close();
	m_reply.reset();
	QFile doneFile(PathCombine(lwjglTargetPath, "done"));
	doneFile.open(QIODevice::WriteOnly);
	doneFile.write("done.");
	doneFile.close();
}
コード例 #5
0
ファイル: OneSixUpdate.cpp プロジェクト: Mattia98/MultiMC5
void OneSixUpdate::assetsFailed()
{
	emitFailed("Failed to download assets!");
}
コード例 #6
0
ファイル: OneSixUpdate.cpp プロジェクト: Mattia98/MultiMC5
void OneSixUpdate::jarlibStart()
{
	setStatus(tr("Getting the library files from Mojang..."));
	QLOG_INFO() << m_inst->name() << ": downloading libraries";
	OneSixInstance *inst = (OneSixInstance *)m_inst;
	bool successful = inst->reloadFullVersion();
	if (!successful)
	{
		emitFailed("Failed to load the version description file. It might be "
				   "corrupted, missing or simply too new.");
		return;
	}

	// Build a list of URLs that will need to be downloaded.
	std::shared_ptr<OneSixVersion> version = inst->getFullVersion();
	// minecraft.jar for this version
	{
		QString version_id = version->id;
		QString localPath = version_id + "/" + version_id + ".jar";
		QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath;

		auto job = new NetJob("Libraries for instance " + inst->name());

		auto metacache = MMC->metacache();
		auto entry = metacache->resolveEntry("versions", localPath);
		job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));

		jarlibDownloadJob.reset(job);
	}

	auto libs = version->getActiveNativeLibs();
	libs.append(version->getActiveNormalLibs());

	auto metacache = MMC->metacache();
	QList<ForgeXzDownloadPtr> ForgeLibs;
	for (auto lib : libs)
	{
		if (lib->hint() == "local")
			continue;

		QString raw_storage = lib->storagePath();
		QString raw_dl = lib->downloadUrl();

		auto f = [&](QString storage, QString dl)
		{
			auto entry = metacache->resolveEntry("libraries", storage);
			if (entry->stale)
			{
				if (lib->hint() == "forge-pack-xz")
				{
					ForgeLibs.append(ForgeXzDownload::make(storage, entry));
				}
				else
				{
					jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry));
				}
			}
		};
		if (raw_storage.contains("${arch}"))
		{
			QString cooked_storage = raw_storage;
			QString cooked_dl = raw_dl;
			f(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"));
			cooked_storage = raw_storage;
			cooked_dl = raw_dl;
			f(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"));
		}
		else
		{
			f(raw_storage, raw_dl);
		}
	}
	// TODO: think about how to propagate this from the original json file... or IF AT ALL
	QString forgeMirrorList = "http://files.minecraftforge.net/mirror-brand.list";
	if (!ForgeLibs.empty())
	{
		jarlibDownloadJob->addNetAction(
			ForgeMirrors::make(ForgeLibs, jarlibDownloadJob, forgeMirrorList));
	}

	connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
	connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(jarlibFailed()));
	connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
			SIGNAL(progress(qint64, qint64)));

	jarlibDownloadJob->start();
}
コード例 #7
0
ファイル: OneSixUpdate.cpp プロジェクト: Mattia98/MultiMC5
void OneSixUpdate::assetIndexFailed()
{
	emitFailed("Failed to download the assets index!");
}
コード例 #8
0
ファイル: OneSixUpdate.cpp プロジェクト: Mattia98/MultiMC5
void OneSixUpdate::versionFileFailed()
{
	emitFailed("Failed to download the version description. Try again.");
}
コード例 #9
0
void AssetsMigrateTask::executeTask()
{
	this->setStatus(tr("Migrating legacy assets..."));
	this->setProgress(0);

	QDir assets_dir("assets");
	if (!assets_dir.exists())
	{
		emitFailed("Assets directory didn't exist");
		return;
	}
	assets_dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
	int base_length = assets_dir.path().length();

	QList<QString> blacklist = {"indexes", "objects", "virtual"};

	if (!assets_dir.exists("objects"))
		assets_dir.mkdir("objects");
	QDir objects_dir("assets/objects");

	QDirIterator iterator(assets_dir, QDirIterator::Subdirectories);
	int successes = 0;
	int failures = 0;
	while (iterator.hasNext())
	{
		QString currentDir = iterator.next();
		currentDir = currentDir.remove(0, base_length + 1);

		bool ignore = false;
		for (QString blacklisted : blacklist)
		{
			if (currentDir.startsWith(blacklisted))
				ignore = true;
		}

		if (!iterator.fileInfo().isDir() && !ignore)
		{
			QString filename = iterator.filePath();

			QFile input(filename);
			input.open(QIODevice::ReadOnly | QIODevice::WriteOnly);
			QString sha1sum =
				QCryptographicHash::hash(input.readAll(), QCryptographicHash::Sha1)
					.toHex()
					.constData();

			QString object_name = filename.remove(0, base_length + 1);
			QLOG_DEBUG() << "Processing" << object_name << ":" << sha1sum << input.size();

			QString object_tlk = sha1sum.left(2);
			QString object_tlk_dir = objects_dir.path() + "/" + object_tlk;

			QDir tlk_dir(object_tlk_dir);
			if (!tlk_dir.exists())
				objects_dir.mkdir(object_tlk);

			QString new_filename = tlk_dir.path() + "/" + sha1sum;
			QFile new_object(new_filename);
			if (!new_object.exists())
			{
				bool rename_success = input.rename(new_filename);
				QLOG_DEBUG() << " Doesn't exist, copying to" << new_filename << ":"
							 << QString::number(rename_success);
				if (rename_success)
					successes++;
				else
					failures++;
			}
			else
			{
				input.remove();
				QLOG_DEBUG() << " Already exists, deleting original and not copying.";
			}

			this->setProgress(100 * ((successes + failures) / (float) this->m_expected));
		}
	}

	if (successes + failures == 0)
	{
		this->setProgress(100);
		QLOG_DEBUG() << "No legacy assets needed importing.";
	}
	else
	{
		QLOG_DEBUG() << "Finished copying legacy assets:" << successes << "successes and"
					 << failures << "failures.";

		this->setStatus("Cleaning up legacy assets...");
		this->setProgress(100);

		QDirIterator cleanup_iterator(assets_dir);

		while (cleanup_iterator.hasNext())
		{
			QString currentDir = cleanup_iterator.next();
			currentDir = currentDir.remove(0, base_length + 1);

			bool ignore = false;
			for (QString blacklisted : blacklist)
			{
				if (currentDir.startsWith(blacklisted))
					ignore = true;
			}

			if (cleanup_iterator.fileInfo().isDir() && !ignore)
			{
				QString path = cleanup_iterator.filePath();
				QDir folder(path);

				QLOG_DEBUG() << "Cleaning up legacy assets folder:" << path;

				folder.removeRecursively();
			}
		}
	}

	if(failures > 0)
	{
		emitFailed(QString("Failed to migrate %1 legacy assets").arg(failures));
	}
	else
	{
		emitSucceeded();
	}
}
コード例 #10
0
void MCVListLoadTask::list_downloaded()
{
	if(vlistReply->error() != QNetworkReply::QNetworkReply::NoError)
	{
		vlistReply->deleteLater();
		emitFailed("Failed to load Minecraft main version list" + vlistReply->errorString());
		return;
	}
	
	QJsonParseError jsonError;
	QJsonDocument jsonDoc = QJsonDocument::fromJson(vlistReply->readAll(), &jsonError);
	vlistReply->deleteLater();
	
	if (jsonError.error != QJsonParseError::NoError)
	{
		emitFailed("Error parsing version list JSON:" + jsonError.errorString());
		return;
	}

	if(!jsonDoc.isObject())
	{
		emitFailed("Error parsing version list JSON: jsonDoc is not an object");
		return;
	}
	
	QJsonObject root = jsonDoc.object();
	
	// Get the ID of the latest release and the latest snapshot.
	if(!root.value("latest").isObject())
	{
		emitFailed("Error parsing version list JSON: version list is missing 'latest' object");
		return;
	}
	
	QJsonObject latest = root.value("latest").toObject();
	
	QString latestReleaseID = latest.value("release").toString("");
	QString latestSnapshotID = latest.value("snapshot").toString("");
	if(latestReleaseID.isEmpty())
	{
		emitFailed("Error parsing version list JSON: latest release field is missing");
		return;
	}
	if(latestSnapshotID.isEmpty())
	{
		emitFailed("Error parsing version list JSON: latest snapshot field is missing");
		return;
	}

	// Now, get the array of versions.
	if(!root.value("versions").isArray())
	{
		emitFailed("Error parsing version list JSON: version list object is missing 'versions' array");
		return;
	}
	QJsonArray versions = root.value("versions").toArray();
	
	QList<InstVersionPtr > tempList;
	for (int i = 0; i < versions.count(); i++)
	{
		bool is_snapshot = false;
		bool is_latest = false;
		
		// Load the version info.
		if(!versions[i].isObject())
		{
			//FIXME: log this somewhere
			continue;
		}
		QJsonObject version = versions[i].toObject();
		QString versionID = version.value("id").toString("");
		QString versionTimeStr = version.value("releaseTime").toString("");
		QString versionTypeStr = version.value("type").toString("");
		if(versionID.isEmpty() || versionTimeStr.isEmpty() || versionTypeStr.isEmpty())
		{
			//FIXME: log this somewhere
			continue;
		}
		
		// Parse the timestamp.
		QDateTime versionTime = timeFromS3Time(versionTimeStr);
		if(!versionTime.isValid())
		{
			//FIXME: log this somewhere
			continue;
		}
		// Parse the type.
		MinecraftVersion::VersionType versionType;
		// OneSix or Legacy. use filter to determine type
		if (versionTypeStr == "release")
		{
			versionType = legacyWhitelist.contains(versionID)?MinecraftVersion::Legacy:MinecraftVersion::OneSix;
			is_latest = (versionID == latestReleaseID);
			is_snapshot = false;
		}
		else if(versionTypeStr == "snapshot") // It's a snapshot... yay
		{
			versionType = legacyWhitelist.contains(versionID)?MinecraftVersion::Legacy:MinecraftVersion::OneSix;
			is_latest = (versionID == latestSnapshotID);
			is_snapshot = true;
		}
		else if(versionTypeStr == "old_alpha")
		{
			versionType = MinecraftVersion::Nostalgia;
			is_latest = false;
			is_snapshot = false;
		}
		else if(versionTypeStr == "old_beta")
		{
			versionType = MinecraftVersion::Legacy;
			is_latest = false;
			is_snapshot = false;
		}
		else
		{
			//FIXME: log this somewhere
			continue;
		}
		// Get the download URL.
		QString dlUrl = QString(MCVLIST_URLBASE) + versionID + "/";
		
		// Now, we construct the version object and add it to the list.
		QSharedPointer<MinecraftVersion> mcVersion(new MinecraftVersion());
		mcVersion->name = mcVersion->descriptor = versionID;
		mcVersion->timestamp = versionTime.toMSecsSinceEpoch();
		mcVersion->download_url = dlUrl;
		mcVersion->is_latest = is_latest;
		mcVersion->is_snapshot = is_snapshot;
		mcVersion->type = versionType;
		tempList.append(mcVersion);
	}
	m_list->updateListData(tempList);
	
	emitSucceeded();
	return;
}
コード例 #11
0
ファイル: OneSixUpdate.cpp プロジェクト: mafen/MultiMC5
void OneSixUpdate::jarlibStart()
{
	OneSixInstance *inst = (OneSixInstance *)m_inst;
	bool successful = inst->reloadFullVersion();
	if (!successful)
	{
		emitFailed("Failed to load the version description file (version.json). It might be "
				   "corrupted, missing or simply too new.");
		return;
	}

	std::shared_ptr<OneSixVersion> version = inst->getFullVersion();

	// download the right jar, save it in versions/$version/$version.jar
	QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
	urlstr += version->id + "/" + version->id + ".jar";
	QString targetstr("versions/");
	targetstr += version->id + "/" + version->id + ".jar";

	auto job = new NetJob("Libraries for instance " + inst->name());
	job->addNetAction(FileDownload::make(QUrl(urlstr), targetstr));
	jarlibDownloadJob.reset(job);

	auto libs = version->getActiveNativeLibs();
	libs.append(version->getActiveNormalLibs());

	auto metacache = MMC->metacache();
	QList<ForgeXzDownloadPtr> ForgeLibs;
	bool already_forge_xz = false;
	for (auto lib : libs)
	{
		if (lib->hint() == "local")
			continue;
		auto entry = metacache->resolveEntry("libraries", lib->storagePath());
		if (entry->stale)
		{
			if (lib->hint() == "forge-pack-xz")
			{
				ForgeLibs.append(ForgeXzDownload::make(lib->storagePath(), entry));
			}
			else
			{
				jarlibDownloadJob->addNetAction(CacheDownload::make(lib->downloadUrl(), entry));
			}
		}
	}
	// TODO: think about how to propagate this from the original json file... or IF AT ALL
	QString forgeMirrorList = "http://files.minecraftforge.net/mirror-brand.list";
	if (!ForgeLibs.empty())
	{
		jarlibDownloadJob->addNetAction(
			ForgeMirrors::make(ForgeLibs, jarlibDownloadJob, forgeMirrorList));
	}

	connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
	connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(jarlibFailed()));
	connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
			SIGNAL(progress(qint64, qint64)));

	jarlibDownloadJob->start();
}