More refactor.
This commit is contained in:
		| @@ -357,7 +357,7 @@ QMap<QString, int> OneSixModEditDialog::getExistingOrder() const | ||||
| 	QMap<QString, int> order; | ||||
| 	// default | ||||
| 	{ | ||||
| 		for (VersionFinal::VersionFile file : m_version->versionFiles) | ||||
| 		for (auto & file : m_version->versionFiles) | ||||
| 		{ | ||||
| 			if (file.id.startsWith("org.multimc.")) | ||||
| 			{ | ||||
|   | ||||
| @@ -44,6 +44,13 @@ QJsonObject MMCJson::ensureObject(const QJsonValue val, const QString what) | ||||
| 	return val.toObject(); | ||||
| } | ||||
|  | ||||
| QJsonObject MMCJson::ensureObject(const QJsonDocument val, const QString what) | ||||
| { | ||||
| 	if (!val.isObject()) | ||||
| 		throw JSONValidationError(what + " is not an object"); | ||||
| 	return val.object(); | ||||
| } | ||||
|  | ||||
| QString MMCJson::ensureString(const QJsonValue val, const QString what) | ||||
| { | ||||
| 	if (!val.isString()) | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #pragma once | ||||
| #include <QJsonValue> | ||||
| #include <QJsonObject> | ||||
| #include <QJsonDocument> | ||||
| #include <QJsonArray> | ||||
| #include "MMCError.h" | ||||
|  | ||||
| @@ -29,6 +30,9 @@ QJsonValue ensureExists(QJsonValue val, const QString what = "value"); | ||||
| /// make sure the value is converted into an object. throw otherwise. | ||||
| QJsonObject ensureObject(const QJsonValue val, const QString what = "value"); | ||||
|  | ||||
| /// make sure the document is converted into an object. throw otherwise. | ||||
| QJsonObject ensureObject(const QJsonDocument val, const QString what = "value"); | ||||
|  | ||||
| /// make sure the value is converted into an array. throw otherwise. | ||||
| QJsonArray ensureArray(const QJsonValue val, QString what = "value"); | ||||
|  | ||||
|   | ||||
| @@ -26,6 +26,9 @@ | ||||
|  | ||||
| class Rule; | ||||
|  | ||||
| class OneSixLibrary; | ||||
| typedef std::shared_ptr<OneSixLibrary> OneSixLibraryPtr; | ||||
|  | ||||
| class OneSixLibrary | ||||
| { | ||||
| private: | ||||
|   | ||||
| @@ -65,23 +65,23 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi | ||||
| 	if(!external.isEmpty()) for (auto fileName : external) | ||||
| 	{ | ||||
| 		QLOG_INFO() << "Reading" << fileName; | ||||
| 		VersionFile file = parseJsonFile(QFileInfo(fileName), false, fileName.endsWith("pack.json")); | ||||
| 		file.name = QFileInfo(fileName).fileName(); | ||||
| 		file.fileId = "org.multimc.external." + file.name; | ||||
| 		file.version = QString(); | ||||
| 		file.mcVersion = QString(); | ||||
| 		file.applyTo(m_version); | ||||
| 		auto file = parseJsonFile(QFileInfo(fileName), false, fileName.endsWith("pack.json")); | ||||
| 		file->name = QFileInfo(fileName).fileName(); | ||||
| 		file->fileId = "org.multimc.external." + file->name; | ||||
| 		file->version = QString(); | ||||
| 		file->mcVersion = QString(); | ||||
| 		file->applyTo(m_version); | ||||
| 	} | ||||
| 	// else, if there's custom json, we just do that. | ||||
| 	else if (QFile::exists(root.absoluteFilePath("custom.json"))) | ||||
| 	{ | ||||
| 		QLOG_INFO() << "Reading custom.json"; | ||||
| 		VersionFile file = parseJsonFile(QFileInfo(root.absoluteFilePath("custom.json")), false); | ||||
| 		file.name = "custom.json"; | ||||
| 		file.filename = "custom.json"; | ||||
| 		file.fileId = "org.multimc.custom.json"; | ||||
| 		file.version = QString(); | ||||
| 		file.applyTo(m_version); | ||||
| 		auto file = parseJsonFile(QFileInfo(root.absoluteFilePath("custom.json")), false); | ||||
| 		file->name = "custom.json"; | ||||
| 		file->filename = "custom.json"; | ||||
| 		file->fileId = "org.multimc.custom.json"; | ||||
| 		file->version = QString(); | ||||
| 		file->applyTo(m_version); | ||||
| 		// QObject::tr("The version descriptors of this instance are not compatible with the current version of MultiMC")); | ||||
| 		// QObject::tr("Error while applying %1. Please check MultiMC-0.log for more info.") | ||||
| 	} | ||||
| @@ -90,12 +90,12 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi | ||||
| 	{ | ||||
| 		// version.json | ||||
| 		QLOG_INFO() << "Reading version.json"; | ||||
| 		VersionFile file = parseJsonFile(QFileInfo(root.absoluteFilePath("version.json")), false); | ||||
| 		file.name = "Minecraft"; | ||||
| 		file.fileId = "org.multimc.version.json"; | ||||
| 		file.version = m_instance->intendedVersionId(); | ||||
| 		file.mcVersion = m_instance->intendedVersionId(); | ||||
| 		file.applyTo(m_version); | ||||
| 		auto file = parseJsonFile(QFileInfo(root.absoluteFilePath("version.json")), false); | ||||
| 		file->name = "Minecraft"; | ||||
| 		file->fileId = "org.multimc.version.json"; | ||||
| 		file->version = m_instance->intendedVersionId(); | ||||
| 		file->mcVersion = m_instance->intendedVersionId(); | ||||
| 		file->applyTo(m_version); | ||||
| 		// QObject::tr("Error while applying %1. Please check MultiMC-0.log for more info.").arg(root.absoluteFilePath("version.json"))); | ||||
|  | ||||
| 		if (onlyVanilla) | ||||
| @@ -105,26 +105,26 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi | ||||
| 		// load all, put into map for ordering, apply in the right order | ||||
| 		QMap<QString, int> overrideOrder = readOverrideOrders(m_instance); | ||||
|  | ||||
| 		QMap<int, QPair<QString, VersionFile>> files; | ||||
| 		QMap<int, QPair<QString, VersionFilePtr>> files; | ||||
| 		for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files)) | ||||
| 		{ | ||||
| 			QLOG_INFO() << "Reading" << info.fileName(); | ||||
| 			VersionFile file = parseJsonFile(info, true); | ||||
| 			if (overrideOrder.contains(file.fileId)) | ||||
| 			auto file = parseJsonFile(info, true); | ||||
| 			if (overrideOrder.contains(file->fileId)) | ||||
| 			{ | ||||
| 				file.order = overrideOrder.value(file.fileId); | ||||
| 				file->order = overrideOrder.value(file->fileId); | ||||
| 			} | ||||
| 			if (files.contains(file.order)) | ||||
| 			if (files.contains(file->order)) | ||||
| 			{ | ||||
| 				throw VersionBuildError(QObject::tr("%1 has the same order as %2").arg(file.fileId, files[file.order].second.fileId)); | ||||
| 				throw VersionBuildError(QObject::tr("%1 has the same order as %2").arg(file->fileId, files[file->order].second->fileId)); | ||||
| 			} | ||||
| 			files.insert(file.order, qMakePair(info.fileName(), file)); | ||||
| 			files.insert(file->order, qMakePair(info.fileName(), file)); | ||||
| 		} | ||||
| 		for (auto order : files.keys()) | ||||
| 		{ | ||||
| 			QLOG_DEBUG() << "Applying file with order" << order; | ||||
| 			auto & filePair = files[order]; | ||||
| 			filePair.second.applyTo(m_version); | ||||
| 			filePair.second->applyTo(m_version); | ||||
| 		} | ||||
| 	} while(0); | ||||
|  | ||||
| @@ -163,15 +163,15 @@ void OneSixVersionBuilder::readJsonAndApply(const QJsonObject &obj) | ||||
| { | ||||
| 	m_version->clear(); | ||||
|  | ||||
| 	VersionFile file = VersionFile::fromJson(QJsonDocument(obj), QString(), false); | ||||
| 	auto file = VersionFile::fromJson(QJsonDocument(obj), QString(), false); | ||||
| 	// QObject::tr("Error while reading. Please check MultiMC-0.log for more info.")); | ||||
|  | ||||
| 	file.applyTo(m_version); | ||||
| 	file->applyTo(m_version); | ||||
| 	// QObject::tr("Error while applying. Please check MultiMC-0.log for more info.")); | ||||
| 	// QObject::tr("The version descriptors of this instance are not compatible with the current version of MultiMC")); | ||||
| } | ||||
|  | ||||
| VersionFile OneSixVersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB) | ||||
| VersionFilePtr OneSixVersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB) | ||||
| { | ||||
| 	QFile file(fileInfo.absoluteFilePath()); | ||||
| 	if (!file.open(QFile::ReadOnly)) | ||||
| @@ -193,39 +193,50 @@ VersionFile OneSixVersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const | ||||
| QMap<QString, int> OneSixVersionBuilder::readOverrideOrders(OneSixInstance *instance) | ||||
| { | ||||
| 	QMap<QString, int> out; | ||||
| 	if (QDir(instance->instanceRoot()).exists("order.json")) | ||||
|  | ||||
| 	// make sure the order file exists | ||||
| 	if (!QDir(instance->instanceRoot()).exists("order.json")) | ||||
| 		return out; | ||||
|  | ||||
| 	// and it can be opened | ||||
| 	QFile orderFile(instance->instanceRoot() + "/order.json"); | ||||
| 	if (!orderFile.open(QFile::ReadOnly)) | ||||
| 	{ | ||||
| 		QFile orderFile(instance->instanceRoot() + "/order.json"); | ||||
| 		if (!orderFile.open(QFile::ReadOnly)) | ||||
| 		QLOG_ERROR() << "Couldn't open" << orderFile.fileName() | ||||
| 						<< " for reading:" << orderFile.errorString(); | ||||
| 		QLOG_WARN() << "Ignoring overriden order"; | ||||
| 		return out; | ||||
| 	} | ||||
|  | ||||
| 	// and it's valid JSON | ||||
| 	QJsonParseError error; | ||||
| 	QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error); | ||||
| 	if (error.error != QJsonParseError::NoError ) | ||||
| 	{ | ||||
| 		QLOG_ERROR() << "Couldn't parse" << orderFile.fileName() << ":"	<< error.errorString(); | ||||
| 		QLOG_WARN() << "Ignoring overriden order"; | ||||
| 		return out; | ||||
| 	} | ||||
|  | ||||
| 	// and then read it and process it if all above is true. | ||||
| 	try | ||||
| 	{ | ||||
| 		auto obj = MMCJson::ensureObject(doc); | ||||
| 		for (auto it = obj.begin(); it != obj.end(); ++it) | ||||
| 		{ | ||||
| 			QLOG_ERROR() << "Couldn't open" << orderFile.fileName() | ||||
| 						 << " for reading:" << orderFile.errorString(); | ||||
| 			QLOG_WARN() << "Ignoring overriden order"; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			QJsonParseError error; | ||||
| 			QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error); | ||||
| 			if (error.error != QJsonParseError::NoError || !doc.isObject()) | ||||
| 			if (it.key().startsWith("org.multimc.")) | ||||
| 			{ | ||||
| 				QLOG_ERROR() << "Couldn't parse" << orderFile.fileName() << ":" | ||||
| 							 << error.errorString(); | ||||
| 				QLOG_WARN() << "Ignoring overriden order"; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				QJsonObject obj = doc.object(); | ||||
| 				for (auto it = obj.begin(); it != obj.end(); ++it) | ||||
| 				{ | ||||
| 					if (it.key().startsWith("org.multimc.")) | ||||
| 					{ | ||||
| 						continue; | ||||
| 					} | ||||
| 					out.insert(it.key(), it.value().toDouble()); | ||||
| 				} | ||||
| 				continue; | ||||
| 			} | ||||
| 			out.insert(it.key(), MMCJson::ensureInteger(it.value())); | ||||
| 		} | ||||
| 	} | ||||
| 	catch (JSONValidationError err) | ||||
| 	{ | ||||
| 		QLOG_ERROR() << "Couldn't parse" << orderFile.fileName() << ": bad file format"; | ||||
| 		QLOG_WARN() << "Ignoring overriden order"; | ||||
| 		return out; | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -43,5 +43,6 @@ private: | ||||
| 	void readJsonAndApply(const QJsonObject &obj); | ||||
| 	void finalizeVersion(); | ||||
|  | ||||
| 	VersionFile parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB = false); | ||||
| 	VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, | ||||
| 							  bool isFTB = false); | ||||
| }; | ||||
|   | ||||
| @@ -13,16 +13,15 @@ using namespace MMCJson; | ||||
|  | ||||
| #define CURRENT_MINIMUM_LAUNCHER_VERSION 14 | ||||
|  | ||||
| RawLibrary RawLibrary::fromJson(const QJsonObject &libObj, | ||||
| 													const QString &filename) | ||||
| RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename) | ||||
| { | ||||
| 	RawLibrary out; | ||||
| 	RawLibraryPtr out(new RawLibrary()); | ||||
| 	if (!libObj.contains("name")) | ||||
| 	{ | ||||
| 		throw JSONValidationError(filename + | ||||
| 								  "contains a library that doesn't have a 'name' field"); | ||||
| 	} | ||||
| 	out.name = libObj.value("name").toString(); | ||||
| 	out->name = libObj.value("name").toString(); | ||||
|  | ||||
| 	auto readString = [libObj, filename](const QString & key, QString & variable) | ||||
| 	{ | ||||
| @@ -40,22 +39,22 @@ RawLibrary RawLibrary::fromJson(const QJsonObject &libObj, | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	readString("url", out.url); | ||||
| 	readString("MMC-hint", out.hint); | ||||
| 	readString("MMC-absulute_url", out.absoluteUrl); | ||||
| 	readString("MMC-absoluteUrl", out.absoluteUrl); | ||||
| 	readString("url", out->url); | ||||
| 	readString("MMC-hint", out->hint); | ||||
| 	readString("MMC-absulute_url", out->absoluteUrl); | ||||
| 	readString("MMC-absoluteUrl", out->absoluteUrl); | ||||
| 	if (libObj.contains("extract")) | ||||
| 	{ | ||||
| 		out.applyExcludes = true; | ||||
| 		out->applyExcludes = true; | ||||
| 		auto extractObj = ensureObject(libObj.value("extract")); | ||||
| 		for (auto excludeVal : ensureArray(extractObj.value("exclude"))) | ||||
| 		{ | ||||
| 			out.excludes.append(ensureString(excludeVal)); | ||||
| 			out->excludes.append(ensureString(excludeVal)); | ||||
| 		} | ||||
| 	} | ||||
| 	if (libObj.contains("natives")) | ||||
| 	{ | ||||
| 		out.applyNatives = true; | ||||
| 		out->applyNatives = true; | ||||
| 		QJsonObject nativesObj = ensureObject(libObj.value("natives")); | ||||
| 		for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) | ||||
| 		{ | ||||
| @@ -66,22 +65,22 @@ RawLibrary RawLibrary::fromJson(const QJsonObject &libObj, | ||||
| 			OpSys opSys = OpSys_fromString(it.key()); | ||||
| 			if (opSys != Os_Other) | ||||
| 			{ | ||||
| 				out.natives.append(qMakePair(opSys, it.value().toString())); | ||||
| 				out->natives.append(qMakePair(opSys, it.value().toString())); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (libObj.contains("rules")) | ||||
| 	{ | ||||
| 		out.applyRules = true; | ||||
| 		out.rules = rulesFromJsonV4(libObj); | ||||
| 		out->applyRules = true; | ||||
| 		out->rules = rulesFromJsonV4(libObj); | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filename, | ||||
| VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &filename, | ||||
| 								  const bool requireOrder, const bool isFTB) | ||||
| { | ||||
| 	VersionFile out; | ||||
| 	VersionFilePtr out(new VersionFile()); | ||||
| 	if (doc.isEmpty() || doc.isNull()) | ||||
| 	{ | ||||
| 		throw JSONValidationError(filename + " is empty or null"); | ||||
| @@ -97,7 +96,7 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 	{ | ||||
| 		if (root.contains("order")) | ||||
| 		{ | ||||
| 			out.order = ensureInteger(root.value("order")); | ||||
| 			out->order = ensureInteger(root.value("order")); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -106,11 +105,11 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	out.name = root.value("name").toString(); | ||||
| 	out.fileId = root.value("fileId").toString(); | ||||
| 	out.version = root.value("version").toString(); | ||||
| 	out.mcVersion = root.value("mcVersion").toString(); | ||||
| 	out.filename = filename; | ||||
| 	out->name = root.value("name").toString(); | ||||
| 	out->fileId = root.value("fileId").toString(); | ||||
| 	out->version = root.value("version").toString(); | ||||
| 	out->mcVersion = root.value("mcVersion").toString(); | ||||
| 	out->filename = filename; | ||||
|  | ||||
| 	auto readString = [root, filename](const QString & key, QString & variable) | ||||
| 	{ | ||||
| @@ -123,30 +122,30 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 	// FIXME: This should be ignored when applying. | ||||
| 	if (!isFTB) | ||||
| 	{ | ||||
| 		readString("id", out.id); | ||||
| 		readString("id", out->id); | ||||
| 	} | ||||
|  | ||||
| 	readString("mainClass", out.mainClass); | ||||
| 	readString("processArguments", out.processArguments); | ||||
| 	readString("minecraftArguments", out.overwriteMinecraftArguments); | ||||
| 	readString("+minecraftArguments", out.addMinecraftArguments); | ||||
| 	readString("-minecraftArguments", out.removeMinecraftArguments); | ||||
| 	readString("type", out.type); | ||||
| 	readString("releaseTime", out.releaseTime); | ||||
| 	readString("time", out.time); | ||||
| 	readString("assets", out.assets); | ||||
| 	readString("mainClass", out->mainClass); | ||||
| 	readString("processArguments", out->processArguments); | ||||
| 	readString("minecraftArguments", out->overwriteMinecraftArguments); | ||||
| 	readString("+minecraftArguments", out->addMinecraftArguments); | ||||
| 	readString("-minecraftArguments", out->removeMinecraftArguments); | ||||
| 	readString("type", out->type); | ||||
| 	readString("releaseTime", out->releaseTime); | ||||
| 	readString("time", out->time); | ||||
| 	readString("assets", out->assets); | ||||
|  | ||||
| 	if (root.contains("minimumLauncherVersion")) | ||||
| 	{ | ||||
| 		out.minimumLauncherVersion = ensureInteger(root.value("minimumLauncherVersion")); | ||||
| 		out->minimumLauncherVersion = ensureInteger(root.value("minimumLauncherVersion")); | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("tweakers")) | ||||
| 	{ | ||||
| 		out.shouldOverwriteTweakers = true; | ||||
| 		out->shouldOverwriteTweakers = true; | ||||
| 		for (auto tweakerVal : ensureArray(root.value("tweakers"))) | ||||
| 		{ | ||||
| 			out.overwriteTweakers.append(ensureString(tweakerVal)); | ||||
| 			out->overwriteTweakers.append(ensureString(tweakerVal)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -154,7 +153,7 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 	{ | ||||
| 		for (auto tweakerVal : ensureArray(root.value("+tweakers"))) | ||||
| 		{ | ||||
| 			out.addTweakers.append(ensureString(tweakerVal)); | ||||
| 			out->addTweakers.append(ensureString(tweakerVal)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -162,29 +161,29 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 	{ | ||||
| 		for (auto tweakerVal : ensureArray(root.value("-tweakers"))) | ||||
| 		{ | ||||
| 			out.removeTweakers.append(ensureString(tweakerVal)); | ||||
| 			out->removeTweakers.append(ensureString(tweakerVal)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("libraries")) | ||||
| 	{ | ||||
| 		// FIXME: This should be done when applying. | ||||
| 		out.shouldOverwriteLibs = !isFTB; | ||||
| 		out->shouldOverwriteLibs = !isFTB; | ||||
| 		for (auto libVal : ensureArray(root.value("libraries"))) | ||||
| 		{ | ||||
| 			auto libObj = ensureObject(libVal); | ||||
|  | ||||
| 			RawLibrary lib = RawLibrary::fromJson(libObj, filename); | ||||
| 			auto lib = RawLibrary::fromJson(libObj, filename); | ||||
| 			// FIXME: This should be done when applying. | ||||
| 			if (isFTB) | ||||
| 			{ | ||||
| 				lib.hint = "local"; | ||||
| 				lib.insertType = RawLibrary::Prepend; | ||||
| 				out.addLibs.prepend(lib); | ||||
| 				lib->hint = "local"; | ||||
| 				lib->insertType = RawLibrary::Prepend; | ||||
| 				out->addLibs.prepend(lib); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				out.overwriteLibs.append(lib); | ||||
| 				out->overwriteLibs.append(lib); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -197,7 +196,7 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 			QJsonValue insertVal = ensureExists(libObj.value("insert")); | ||||
|  | ||||
| 			// parse the library | ||||
| 			RawLibrary lib = RawLibrary::fromJson(libObj, filename); | ||||
| 			auto lib = RawLibrary::fromJson(libObj, filename); | ||||
|  | ||||
| 			// TODO: utility functions for handling this case. templates? | ||||
| 			QString insertString; | ||||
| @@ -215,24 +214,24 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 												  filename); | ||||
| 					} | ||||
| 					insertString = insertObj.keys().first(); | ||||
| 					lib.insertData = insertObj.value(insertString).toString(); | ||||
| 					lib->insertData = insertObj.value(insertString).toString(); | ||||
| 				} | ||||
| 			} | ||||
| 			if (insertString == "apply") | ||||
| 			{ | ||||
| 				lib.insertType = RawLibrary::Apply; | ||||
| 				lib->insertType = RawLibrary::Apply; | ||||
| 			} | ||||
| 			else if (insertString == "prepend") | ||||
| 			{ | ||||
| 				lib.insertType = RawLibrary::Prepend; | ||||
| 				lib->insertType = RawLibrary::Prepend; | ||||
| 			} | ||||
| 			else if (insertString == "append") | ||||
| 			{ | ||||
| 				lib.insertType = RawLibrary::Prepend; | ||||
| 				lib->insertType = RawLibrary::Prepend; | ||||
| 			} | ||||
| 			else if (insertString == "replace") | ||||
| 			{ | ||||
| 				lib.insertType = RawLibrary::Replace; | ||||
| 				lib->insertType = RawLibrary::Replace; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| @@ -244,11 +243,11 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 				const QString dependString = ensureString(libObj.value("MMC-depend")); | ||||
| 				if (dependString == "hard") | ||||
| 				{ | ||||
| 					lib.dependType = RawLibrary::Hard; | ||||
| 					lib->dependType = RawLibrary::Hard; | ||||
| 				} | ||||
| 				else if (dependString == "soft") | ||||
| 				{ | ||||
| 					lib.dependType = RawLibrary::Soft; | ||||
| 					lib->dependType = RawLibrary::Soft; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @@ -256,7 +255,7 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 											  " contains an invalid depend type"); | ||||
| 				} | ||||
| 			} | ||||
| 			out.addLibs.append(lib); | ||||
| 			out->addLibs.append(lib); | ||||
| 		} | ||||
| 	} | ||||
| 	if (root.contains("-libraries")) | ||||
| @@ -264,37 +263,36 @@ VersionFile VersionFile::fromJson(const QJsonDocument &doc, const QString &filen | ||||
| 		for (auto libVal : ensureArray(root.value("-libraries"))) | ||||
| 		{ | ||||
| 			auto libObj = ensureObject(libVal); | ||||
| 			out.removeLibs.append(ensureString(libObj.value("name"))); | ||||
| 			out->removeLibs.append(ensureString(libObj.value("name"))); | ||||
| 		} | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<OneSixLibrary> VersionFile::createLibrary(const RawLibrary &lib) | ||||
| OneSixLibraryPtr VersionFile::createLibrary(RawLibraryPtr lib) | ||||
| { | ||||
| 	std::shared_ptr<OneSixLibrary> out(new OneSixLibrary(lib.name)); | ||||
| 	if (!lib.url.isEmpty()) | ||||
| 	std::shared_ptr<OneSixLibrary> out(new OneSixLibrary(lib->name)); | ||||
| 	if (!lib->url.isEmpty()) | ||||
| 	{ | ||||
| 		out->setBaseUrl(lib.url); | ||||
| 		out->setBaseUrl(lib->url); | ||||
| 	} | ||||
| 	out->setHint(lib.hint); | ||||
| 	if (!lib.absoluteUrl.isEmpty()) | ||||
| 	out->setHint(lib->hint); | ||||
| 	if (!lib->absoluteUrl.isEmpty()) | ||||
| 	{ | ||||
| 		out->setAbsoluteUrl(lib.absoluteUrl); | ||||
| 		out->setAbsoluteUrl(lib->absoluteUrl); | ||||
| 	} | ||||
| 	out->setAbsoluteUrl(lib.absoluteUrl); | ||||
| 	out->extract_excludes = lib.excludes; | ||||
| 	for (auto native : lib.natives) | ||||
| 	out->setAbsoluteUrl(lib->absoluteUrl); | ||||
| 	out->extract_excludes = lib->excludes; | ||||
| 	for (auto native : lib->natives) | ||||
| 	{ | ||||
| 		out->addNative(native.first, native.second); | ||||
| 	} | ||||
| 	out->setRules(lib.rules); | ||||
| 	out->setRules(lib->rules); | ||||
| 	out->finalize(); | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| int VersionFile::findLibrary(QList<std::shared_ptr<OneSixLibrary>> haystack, | ||||
| 							 const QString &needle) | ||||
| int VersionFile::findLibrary(QList<OneSixLibraryPtr> haystack, const QString &needle) | ||||
| { | ||||
| 	for (int i = 0; i < haystack.size(); ++i) | ||||
| 	{ | ||||
| @@ -395,48 +393,48 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 	} | ||||
| 	for (auto lib : addLibs) | ||||
| 	{ | ||||
| 		switch (lib.insertType) | ||||
| 		switch (lib->insertType) | ||||
| 		{ | ||||
| 		case RawLibrary::Apply: | ||||
| 		{ | ||||
|  | ||||
| 			int index = findLibrary(version->libraries, lib.name); | ||||
| 			int index = findLibrary(version->libraries, lib->name); | ||||
| 			if (index >= 0) | ||||
| 			{ | ||||
| 				auto library = version->libraries[index]; | ||||
| 				if (!lib.url.isNull()) | ||||
| 				if (!lib->url.isNull()) | ||||
| 				{ | ||||
| 					library->setBaseUrl(lib.url); | ||||
| 					library->setBaseUrl(lib->url); | ||||
| 				} | ||||
| 				if (!lib.hint.isNull()) | ||||
| 				if (!lib->hint.isNull()) | ||||
| 				{ | ||||
| 					library->setHint(lib.hint); | ||||
| 					library->setHint(lib->hint); | ||||
| 				} | ||||
| 				if (!lib.absoluteUrl.isNull()) | ||||
| 				if (!lib->absoluteUrl.isNull()) | ||||
| 				{ | ||||
| 					library->setAbsoluteUrl(lib.absoluteUrl); | ||||
| 					library->setAbsoluteUrl(lib->absoluteUrl); | ||||
| 				} | ||||
| 				if (lib.applyExcludes) | ||||
| 				if (lib->applyExcludes) | ||||
| 				{ | ||||
| 					library->extract_excludes = lib.excludes; | ||||
| 					library->extract_excludes = lib->excludes; | ||||
| 				} | ||||
| 				if (lib.applyNatives) | ||||
| 				if (lib->applyNatives) | ||||
| 				{ | ||||
| 					library->clearSuffixes(); | ||||
| 					for (auto native : lib.natives) | ||||
| 					for (auto native : lib->natives) | ||||
| 					{ | ||||
| 						library->addNative(native.first, native.second); | ||||
| 					} | ||||
| 				} | ||||
| 				if (lib.applyRules) | ||||
| 				if (lib->applyRules) | ||||
| 				{ | ||||
| 					library->setRules(lib.rules); | ||||
| 					library->setRules(lib->rules); | ||||
| 				} | ||||
| 				library->finalize(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				QLOG_WARN() << "Couldn't find" << lib.name << "(skipping)"; | ||||
| 				QLOG_WARN() << "Couldn't find" << lib->name << "(skipping)"; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| @@ -444,12 +442,12 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 		case RawLibrary::Prepend: | ||||
| 		{ | ||||
|  | ||||
| 			const int startOfVersion = lib.name.lastIndexOf(':') + 1; | ||||
| 			const int startOfVersion = lib->name.lastIndexOf(':') + 1; | ||||
| 			const int index = findLibrary( | ||||
| 				version->libraries, QString(lib.name).replace(startOfVersion, INT_MAX, '*')); | ||||
| 				version->libraries, QString(lib->name).replace(startOfVersion, INT_MAX, '*')); | ||||
| 			if (index < 0) | ||||
| 			{ | ||||
| 				if (lib.insertType == RawLibrary::Append) | ||||
| 				if (lib->insertType == RawLibrary::Append) | ||||
| 				{ | ||||
| 					version->libraries.append(createLibrary(lib)); | ||||
| 				} | ||||
| @@ -461,7 +459,7 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 			else | ||||
| 			{ | ||||
| 				auto otherLib = version->libraries.at(index); | ||||
| 				const Util::Version ourVersion = lib.name.mid(startOfVersion, INT_MAX); | ||||
| 				const Util::Version ourVersion = lib->name.mid(startOfVersion, INT_MAX); | ||||
| 				const Util::Version otherVersion = otherLib->version(); | ||||
| 				// if the existing version is a hard dependency we can either use it or | ||||
| 				// fail, but we can't change it | ||||
| @@ -470,12 +468,12 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 					// we need a higher version, or we're hard to and the versions aren't | ||||
| 					// equal | ||||
| 					if (ourVersion > otherVersion || | ||||
| 						(lib.dependType == RawLibrary::Hard && ourVersion != otherVersion)) | ||||
| 						(lib->dependType == RawLibrary::Hard && ourVersion != otherVersion)) | ||||
| 					{ | ||||
| 						throw VersionBuildError( | ||||
| 							QString( | ||||
| 								"Error resolving library dependencies between %1 and %2 in %3.") | ||||
| 								.arg(otherLib->rawName(), lib.name, filename)); | ||||
| 								.arg(otherLib->rawName(), lib->name, filename)); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| @@ -498,11 +496,11 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 					{ | ||||
| 						// our version is smaller than the existing version, but we require | ||||
| 						// it: fail | ||||
| 						if (lib.dependType == RawLibrary::Hard) | ||||
| 						if (lib->dependType == RawLibrary::Hard) | ||||
| 						{ | ||||
| 							throw VersionBuildError(QString( | ||||
| 								"Error resolving library dependencies between %1 and %2 in %3.") | ||||
| 														.arg(otherLib->rawName(), lib.name, | ||||
| 														.arg(otherLib->rawName(), lib->name, | ||||
| 															 filename)); | ||||
| 						} | ||||
| 					} | ||||
| @@ -512,14 +510,14 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 		} | ||||
| 		case RawLibrary::Replace: | ||||
| 		{ | ||||
| 			int index = findLibrary(version->libraries, lib.insertData); | ||||
| 			int index = findLibrary(version->libraries, lib->insertData); | ||||
| 			if (index >= 0) | ||||
| 			{ | ||||
| 				version->libraries.replace(index, createLibrary(lib)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				QLOG_WARN() << "Couldn't find" << lib.insertData << "(skipping)"; | ||||
| 				QLOG_WARN() << "Couldn't find" << lib->insertData << "(skipping)"; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| @@ -537,13 +535,4 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 			QLOG_WARN() << "Couldn't find" << lib << "(skipping)"; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	VersionFinal::VersionFile versionFile; | ||||
| 	versionFile.name = name; | ||||
| 	versionFile.id = fileId; | ||||
| 	versionFile.version = this->version; | ||||
| 	versionFile.mcVersion = mcVersion; | ||||
| 	versionFile.filename = filename; | ||||
| 	versionFile.order = order; | ||||
| 	version->versionFiles.append(versionFile); | ||||
| } | ||||
|   | ||||
| @@ -20,6 +20,8 @@ public: | ||||
| 	virtual ~VersionBuildError() {}; | ||||
| }; | ||||
|  | ||||
| struct RawLibrary; | ||||
| typedef std::shared_ptr<RawLibrary> RawLibraryPtr; | ||||
| struct RawLibrary | ||||
| { | ||||
| 	QString name; | ||||
| @@ -50,17 +52,19 @@ struct RawLibrary | ||||
| 	}; | ||||
| 	DependType dependType = Soft; | ||||
|  | ||||
| 	static RawLibrary fromJson(const QJsonObject &libObj, const QString &filename); | ||||
| 	static RawLibraryPtr fromJson(const QJsonObject &libObj, const QString &filename); | ||||
| }; | ||||
|  | ||||
| struct VersionFile; | ||||
| typedef std::shared_ptr<VersionFile> VersionFilePtr; | ||||
| struct VersionFile | ||||
| { | ||||
| public: /* methods */ | ||||
| 	static VersionFile fromJson(const QJsonDocument &doc, const QString &filename, | ||||
| 	static VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename, | ||||
| 								const bool requireOrder, const bool isFTB = false); | ||||
|  | ||||
| 	static std::shared_ptr<OneSixLibrary> createLibrary(const RawLibrary &lib); | ||||
| 	int findLibrary(QList<std::shared_ptr<OneSixLibrary>> haystack, const QString &needle); | ||||
| 	static OneSixLibraryPtr createLibrary(RawLibraryPtr lib); | ||||
| 	int findLibrary(QList<OneSixLibraryPtr> haystack, const QString &needle); | ||||
| 	void applyTo(VersionFinal *version); | ||||
|  | ||||
| public: /* data */ | ||||
| @@ -91,7 +95,7 @@ public: /* data */ | ||||
| 	QStringList removeTweakers; | ||||
|  | ||||
| 	bool shouldOverwriteLibs = false; | ||||
| 	QList<RawLibrary> overwriteLibs; | ||||
| 	QList<RawLibrary> addLibs; | ||||
| 	QList<RawLibraryPtr> overwriteLibs; | ||||
| 	QList<RawLibraryPtr> addLibs; | ||||
| 	QList<QString> removeLibs; | ||||
| }; | ||||
| @@ -52,26 +52,6 @@ void VersionFinal::clear() | ||||
| 	endResetModel(); | ||||
| } | ||||
|  | ||||
| void VersionFinal::dump() const | ||||
| { | ||||
| 	qDebug().nospace() << "VersionFinal(" | ||||
| 				  << "\n\tid=" << id | ||||
| 				  << "\n\ttime=" << time | ||||
| 				  << "\n\treleaseTime=" << releaseTime | ||||
| 				  << "\n\ttype=" << type | ||||
| 				  << "\n\tassets=" << assets | ||||
| 				  << "\n\tprocessArguments=" << processArguments | ||||
| 				  << "\n\tminecraftArguments=" << minecraftArguments | ||||
| 				  << "\n\tminimumLauncherVersion=" << minimumLauncherVersion | ||||
| 				  << "\n\tmainClass=" << mainClass | ||||
| 				  << "\n\tlibraries="; | ||||
| 	for (auto lib : libraries) | ||||
| 	{ | ||||
| 		qDebug().nospace() << "\n\t\t" << lib.get(); | ||||
| 	} | ||||
| 	qDebug().nospace() << "\n)"; | ||||
| } | ||||
|  | ||||
| bool VersionFinal::canRemove(const int index) const | ||||
| { | ||||
| 	if (index < versionFiles.size()) | ||||
| @@ -201,25 +181,3 @@ int VersionFinal::columnCount(const QModelIndex &parent) const | ||||
| { | ||||
| 	return 2; | ||||
| } | ||||
|  | ||||
| QDebug operator<<(QDebug &dbg, const VersionFinal *version) | ||||
| { | ||||
| 	version->dump(); | ||||
| 	return dbg.maybeSpace(); | ||||
| } | ||||
| QDebug operator<<(QDebug &dbg, const OneSixLibrary *library) | ||||
| { | ||||
| 	dbg.nospace() << "OneSixLibrary(" | ||||
| 				  << "\n\t\t\trawName=" << library->rawName() | ||||
| 				  << "\n\t\t\tname=" << library->name() | ||||
| 				  << "\n\t\t\tversion=" << library->version() | ||||
| 				  << "\n\t\t\ttype=" << library->type() | ||||
| 				  << "\n\t\t\tisActive=" << library->isActive() | ||||
| 				  << "\n\t\t\tisNative=" << library->isNative() | ||||
| 				  << "\n\t\t\tdownloadUrl=" << library->downloadUrl() | ||||
| 				  << "\n\t\t\tstoragePath=" << library->storagePath() | ||||
| 				  << "\n\t\t\tabsolutePath=" << library->absoluteUrl() | ||||
| 				  << "\n\t\t\thint=" << library->hint(); | ||||
| 	dbg.nospace() << "\n\t\t)"; | ||||
| 	return dbg.maybeSpace(); | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
| #include <memory> | ||||
|  | ||||
| #include "OneSixLibrary.h" | ||||
| #include "VersionFile.h" | ||||
|  | ||||
| class OneSixInstance; | ||||
|  | ||||
| @@ -118,15 +119,6 @@ public: | ||||
| 	*/ | ||||
| 	// QList<Rule> rules; | ||||
|  | ||||
| 	struct VersionFile | ||||
| 	{ | ||||
| 		QString name; | ||||
| 		QString id; | ||||
| 		QString version; | ||||
| 		QString mcVersion; | ||||
| 		QString filename; | ||||
| 		int order; | ||||
| 	}; | ||||
| 	QList<VersionFile> versionFiles; | ||||
|  | ||||
| private: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user