Lock down the version cache. Just enough to make it annoying to corrupt the files.
This commit is contained in:
		| @@ -50,6 +50,7 @@ | ||||
| #include "CustomMessageBox.h" | ||||
| #include <QDesktopServices> | ||||
| #include <QMessageBox> | ||||
| #include <QListView> | ||||
| #include <QString> | ||||
| #include <QUrl> | ||||
|  | ||||
| @@ -171,6 +172,26 @@ void InstanceEditDialog::on_removeLibraryBtn_clicked() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void InstanceEditDialog::on_jarmodBtn_clicked() | ||||
| { | ||||
| 	QFileDialog w; | ||||
| 	w.setFileMode(QFileDialog::AnyFile); | ||||
| 	// w.setOption(QFileDialog::DontUseNativeDialog, true); | ||||
| 	QListView *l = w.findChild<QListView *>("listView"); | ||||
| 	if (l) | ||||
| 	{ | ||||
| 		l->setSelectionMode(QAbstractItemView::ExtendedSelection); | ||||
| 	} | ||||
| 	QTreeView *t = w.findChild<QTreeView *>(); | ||||
| 	if (t) | ||||
| 	{ | ||||
| 		t->setSelectionMode(QAbstractItemView::ExtendedSelection); | ||||
| 	} | ||||
| 	int result = w.exec(); | ||||
| 	auto list = w.selectedFiles(); | ||||
| 	QLOG_INFO() << list.join(" "); | ||||
| } | ||||
|  | ||||
| void InstanceEditDialog::on_resetLibraryOrderBtn_clicked() | ||||
| { | ||||
| 	try | ||||
| @@ -192,8 +213,10 @@ void InstanceEditDialog::on_moveLibraryUpBtn_clicked() | ||||
| 	try | ||||
| 	{ | ||||
| 		const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); | ||||
| 		const int newRow = 0;m_version->move(row, VersionFinal::MoveUp); | ||||
| 		//ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect); | ||||
| 		const int newRow = 0; | ||||
| 		m_version->move(row, VersionFinal::MoveUp); | ||||
| 		// ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), | ||||
| 		// QItemSelectionModel::ClearAndSelect); | ||||
| 	} | ||||
| 	catch (MMCError &e) | ||||
| 	{ | ||||
| @@ -210,8 +233,10 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked() | ||||
| 	try | ||||
| 	{ | ||||
| 		const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); | ||||
| 		const int newRow = 0;m_version->move(row, VersionFinal::MoveDown); | ||||
| 		//ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect); | ||||
| 		const int newRow = 0; | ||||
| 		m_version->move(row, VersionFinal::MoveDown); | ||||
| 		// ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), | ||||
| 		// QItemSelectionModel::ClearAndSelect); | ||||
| 	} | ||||
| 	catch (MMCError &e) | ||||
| 	{ | ||||
| @@ -221,7 +246,8 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked() | ||||
|  | ||||
| void InstanceEditDialog::on_changeMCVersionBtn_clicked() | ||||
| { | ||||
| 	VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"), this); | ||||
| 	VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"), | ||||
| 								this); | ||||
| 	if (!vselect.exec() || !vselect.selectedVersion()) | ||||
| 		return; | ||||
|  | ||||
| @@ -266,8 +292,9 @@ void InstanceEditDialog::on_forgeBtn_clicked() | ||||
| 	// FIXME: use actual model, not reloading. Move logic to model. | ||||
| 	if (m_version->hasFtbPack()) | ||||
| 	{ | ||||
| 		if (QMessageBox::question(this, tr("Revert?"), | ||||
| 								  tr("This action will remove the FTB pack version patch. Continue?")) != | ||||
| 		if (QMessageBox::question( | ||||
| 				this, tr("Revert?"), | ||||
| 				tr("This action will remove the FTB pack version patch. Continue?")) != | ||||
| 			QMessageBox::Yes) | ||||
| 		{ | ||||
| 			return; | ||||
| @@ -293,7 +320,8 @@ void InstanceEditDialog::on_forgeBtn_clicked() | ||||
| 	if (vselect.exec() && vselect.selectedVersion()) | ||||
| 	{ | ||||
| 		ProgressDialog dialog(this); | ||||
| 		dialog.exec(ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); | ||||
| 		dialog.exec( | ||||
| 			ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -301,8 +329,9 @@ void InstanceEditDialog::on_liteloaderBtn_clicked() | ||||
| { | ||||
| 	if (m_version->hasFtbPack()) | ||||
| 	{ | ||||
| 		if (QMessageBox::question(this, tr("Revert?"), | ||||
| 								  tr("This action will remove the FTB pack version patch. Continue?")) != | ||||
| 		if (QMessageBox::question( | ||||
| 				this, tr("Revert?"), | ||||
| 				tr("This action will remove the FTB pack version patch. Continue?")) != | ||||
| 			QMessageBox::Yes) | ||||
| 		{ | ||||
| 			return; | ||||
| @@ -329,7 +358,8 @@ void InstanceEditDialog::on_liteloaderBtn_clicked() | ||||
| 	if (vselect.exec() && vselect.selectedVersion()) | ||||
| 	{ | ||||
| 		ProgressDialog dialog(this); | ||||
| 		dialog.exec(LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); | ||||
| 		dialog.exec( | ||||
| 			LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -497,8 +527,7 @@ void InstanceEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous | ||||
| 	ui->frame->updateWithMod(m); | ||||
| } | ||||
|  | ||||
| void InstanceEditDialog::versionCurrent(const QModelIndex ¤t, | ||||
| 										 const QModelIndex &previous) | ||||
| void InstanceEditDialog::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
|   | ||||
| @@ -44,6 +44,7 @@ slots: | ||||
| 	void on_resetLibraryOrderBtn_clicked(); | ||||
| 	void on_moveLibraryUpBtn_clicked(); | ||||
| 	void on_moveLibraryDownBtn_clicked(); | ||||
| 	void on_jarmodBtn_clicked(); | ||||
|  | ||||
| 	// loader mod tab | ||||
| 	void on_addModBtn_clicked(); | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #include "logic/OneSixInstance_p.h" | ||||
| #include "logic/OneSixUpdate.h" | ||||
| #include "logic/minecraft/VersionFinal.h" | ||||
| #include "minecraft/VersionBuildError.h" | ||||
|  | ||||
| #include "logic/assets/AssetsUtils.h" | ||||
| #include "icons/IconList.h" | ||||
| @@ -42,21 +43,13 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, | ||||
|  | ||||
| void OneSixInstance::init() | ||||
| { | ||||
| 	// FIXME: why is this decided here? what does this even mean? | ||||
| 	if (QDir(instanceRoot()).exists("version.json")) | ||||
| 	try | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			reloadVersion(); | ||||
| 		} | ||||
| 		catch (MMCError &e) | ||||
| 		{ | ||||
| 			// QLOG_ERROR() << "Caught exception on instance init: " << e.cause(); | ||||
| 		} | ||||
| 		reloadVersion(); | ||||
| 	} | ||||
| 	else | ||||
| 	catch (MMCError &e) | ||||
| 	{ | ||||
| 		clearVersion(); | ||||
| 		QLOG_ERROR() << "Caught exception on instance init: " << e.cause(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -388,6 +381,10 @@ void OneSixInstance::reloadVersion() | ||||
| 		d->version->reload(externalPatches()); | ||||
| 		d->m_flags.remove(VersionBrokenFlag); | ||||
| 		emit versionReloaded(); | ||||
| 	} | ||||
| 	catch (VersionIncomplete & error) | ||||
| 	{ | ||||
| 		 | ||||
| 	} | ||||
| 	catch (MMCError &error) | ||||
| 	{ | ||||
|   | ||||
| @@ -56,9 +56,9 @@ bool MinecraftVersion::isMinecraftVersion() | ||||
| // 2. if discrepancies are found, fall out and fail (impossible to apply incomplete version). | ||||
| void MinecraftVersion::applyFileTo(VersionFinal *version) | ||||
| { | ||||
| 	QFileInfo versionFile(QString("versions/%1/%1.json").arg(m_descriptor)); | ||||
| 	QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_descriptor)); | ||||
| 	 | ||||
| 	auto versionObj = VersionBuilder::parseJsonFile(versionFile, false, false); | ||||
| 	auto versionObj = VersionBuilder::parseBinaryJsonFile(versionFile); | ||||
| 	versionObj->applyTo(version); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -29,6 +29,8 @@ | ||||
| #include <logic/VersionFilterData.h> | ||||
| #include <pathutils.h> | ||||
|  | ||||
| static const char * localVersionCache = "versions/versions.dat"; | ||||
|  | ||||
| class ListLoadError : public MMCError | ||||
| { | ||||
| public: | ||||
| @@ -78,7 +80,7 @@ void MinecraftVersionList::sortInternal() | ||||
|  | ||||
| void MinecraftVersionList::loadCachedList() | ||||
| { | ||||
| 	QFile localIndex("versions/versions.json"); | ||||
| 	QFile localIndex(localVersionCache); | ||||
| 	if (!localIndex.exists()) | ||||
| 	{ | ||||
| 		return; | ||||
| @@ -92,13 +94,18 @@ void MinecraftVersionList::loadCachedList() | ||||
| 	auto data = localIndex.readAll(); | ||||
| 	try | ||||
| 	{ | ||||
| 		loadMojangList(data, Local); | ||||
| 		localIndex.close(); | ||||
| 		QJsonDocument jsonDoc = QJsonDocument::fromBinaryData(data); | ||||
| 		if (jsonDoc.isNull()) | ||||
| 		{ | ||||
| 			throw ListLoadError(tr("Error reading the version list.")); | ||||
| 		} | ||||
| 		loadMojangList(jsonDoc, Local); | ||||
| 	} | ||||
| 	catch (MMCError &e) | ||||
| 	{ | ||||
| 		// the cache has gone bad for some reason... flush it. | ||||
| 		QLOG_ERROR() << "The minecraft version cache is corrupted. Flushing cache."; | ||||
| 		localIndex.close(); | ||||
| 		localIndex.remove(); | ||||
| 		return; | ||||
| 	} | ||||
| @@ -172,18 +179,10 @@ void MinecraftVersionList::loadBuiltinList() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MinecraftVersionList::loadMojangList(QByteArray data, VersionSource source) | ||||
| void MinecraftVersionList::loadMojangList(QJsonDocument jsonDoc, VersionSource source) | ||||
| { | ||||
| 	QLOG_INFO() << "Loading" << ((source == Remote) ? "remote" : "local") << "version list."; | ||||
| 	QJsonParseError jsonError; | ||||
| 	QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); | ||||
|  | ||||
| 	if (jsonError.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		throw ListLoadError( | ||||
| 			tr("Error parsing version list JSON: %1").arg(jsonError.errorString())); | ||||
| 	} | ||||
| 	 | ||||
| 	if (!jsonDoc.isObject()) | ||||
| 	{ | ||||
| 		throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object")); | ||||
| @@ -391,7 +390,14 @@ void MCVListLoadTask::list_downloaded() | ||||
| 	vlistReply->deleteLater(); | ||||
| 	try | ||||
| 	{ | ||||
| 		m_list->loadMojangList(data, Remote); | ||||
| 		QJsonParseError jsonError; | ||||
| 		QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); | ||||
| 		if (jsonError.error != QJsonParseError::NoError) | ||||
| 		{ | ||||
| 			throw ListLoadError( | ||||
| 				tr("Error parsing version list JSON: %1").arg(jsonError.errorString())); | ||||
| 		} | ||||
| 		m_list->loadMojangList(jsonDoc, Remote); | ||||
| 	} | ||||
| 	catch (MMCError &e) | ||||
| 	{ | ||||
| @@ -474,9 +480,9 @@ void MCVListVersionUpdateTask::json_downloaded() | ||||
|  | ||||
| 	// now dump the file to disk | ||||
| 	auto doc = file->toJson(false); | ||||
| 	auto newdata = doc.toJson(); | ||||
| 	auto newdata = doc.toBinaryData(); | ||||
| 	QLOG_INFO() << newdata; | ||||
| 	QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".json"; | ||||
| 	QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".dat"; | ||||
| 	ensureFilePathExists(targetPath); | ||||
| 	QSaveFile vfile1(targetPath); | ||||
| 	if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly)) | ||||
| @@ -511,9 +517,9 @@ std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version) | ||||
| void MinecraftVersionList::saveCachedList() | ||||
| { | ||||
| 	// FIXME: throw. | ||||
| 	if (!ensureFilePathExists("versions/versions.json")) | ||||
| 	if (!ensureFilePathExists(localVersionCache)) | ||||
| 		return; | ||||
| 	QSaveFile tfile("versions/versions.json"); | ||||
| 	QSaveFile tfile(localVersionCache); | ||||
| 	if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) | ||||
| 		return; | ||||
| 	QJsonObject toplevel; | ||||
| @@ -554,7 +560,7 @@ void MinecraftVersionList::saveCachedList() | ||||
| 	} | ||||
| 	 | ||||
| 	QJsonDocument doc(toplevel); | ||||
| 	QByteArray jsonData = doc.toJson(); | ||||
| 	QByteArray jsonData = doc.toBinaryData(); | ||||
| 	qint64 result = tfile.write(jsonData); | ||||
| 	if (result == -1) | ||||
| 		return; | ||||
|   | ||||
| @@ -34,7 +34,7 @@ class MinecraftVersionList : public BaseVersionList | ||||
| private: | ||||
| 	void sortInternal(); | ||||
| 	void loadBuiltinList(); | ||||
| 	void loadMojangList(QByteArray data, VersionSource source); | ||||
| 	void loadMojangList(QJsonDocument jsonDoc, VersionSource source); | ||||
| 	void loadCachedList(); | ||||
| 	void saveCachedList(); | ||||
| 	void finalizeUpdate(QString version); | ||||
|   | ||||
| @@ -237,6 +237,25 @@ VersionFilePtr VersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const bo | ||||
| 	// info.").arg(file.fileName()); | ||||
| } | ||||
|  | ||||
| VersionFilePtr VersionBuilder::parseBinaryJsonFile(const QFileInfo &fileInfo) | ||||
| { | ||||
| 	QFile file(fileInfo.absoluteFilePath()); | ||||
| 	if (!file.open(QFile::ReadOnly)) | ||||
| 	{ | ||||
| 		throw JSONValidationError(QObject::tr("Unable to open the version file %1: %2.") | ||||
| 									  .arg(fileInfo.fileName(), file.errorString())); | ||||
| 	} | ||||
| 	QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll()); | ||||
| 	file.close(); | ||||
| 	if (doc.isNull()) | ||||
| 	{ | ||||
| 		file.remove(); | ||||
| 		throw JSONValidationError( | ||||
| 			QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName())); | ||||
| 	} | ||||
| 	return VersionFile::fromJson(doc, file.fileName(), false, false); | ||||
| } | ||||
|  | ||||
| QMap<QString, int> VersionBuilder::readOverrideOrders(OneSixInstance *instance) | ||||
| { | ||||
| 	QMap<QString, int> out; | ||||
|   | ||||
| @@ -31,6 +31,7 @@ public: | ||||
| 	static void build(VersionFinal *version, OneSixInstance *instance, const QStringList &external); | ||||
| 	static void readJsonAndApplyToVersion(VersionFinal *version, const QJsonObject &obj); | ||||
| 	static VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB = false); | ||||
| 	static VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo); | ||||
| 	 | ||||
| 	static QMap<QString, int> readOverrideOrders(OneSixInstance *instance); | ||||
| 	static bool writeOverrideOrders(const QMap<QString, int> &order, OneSixInstance *instance); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user