NOISSUE reorganize and document libraries
This commit is contained in:
		
							
								
								
									
										395
									
								
								api/logic/minecraft/ftb/FTBPlugin.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								api/logic/minecraft/ftb/FTBPlugin.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,395 @@ | ||||
| #include "FTBPlugin.h" | ||||
| #include <Env.h> | ||||
| #include "FTBVersion.h" | ||||
| #include "LegacyFTBInstance.h" | ||||
| #include "OneSixFTBInstance.h" | ||||
| #include <BaseInstance.h> | ||||
| #include <InstanceList.h> | ||||
| #include <minecraft/MinecraftVersionList.h> | ||||
| #include <settings/INISettingsObject.h> | ||||
| #include <FileSystem.h> | ||||
| #include "QDebug" | ||||
| #include <QXmlStreamReader> | ||||
| #include <QRegularExpression> | ||||
|  | ||||
| struct FTBRecord | ||||
| { | ||||
| 	QString dirName; | ||||
| 	QString name; | ||||
| 	QString logo; | ||||
| 	QString iconKey; | ||||
| 	QString mcVersion; | ||||
| 	QString description; | ||||
| 	QString instanceDir; | ||||
| 	QString templateDir; | ||||
| 	bool operator==(const FTBRecord other) const | ||||
| 	{ | ||||
| 		return instanceDir == other.instanceDir; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| inline uint qHash(FTBRecord record) | ||||
| { | ||||
| 	return qHash(record.instanceDir); | ||||
| } | ||||
|  | ||||
| QSet<FTBRecord> discoverFTBInstances(SettingsObjectPtr globalSettings) | ||||
| { | ||||
| 	QSet<FTBRecord> records; | ||||
| 	QDir dir = QDir(globalSettings->get("FTBLauncherLocal").toString()); | ||||
| 	QDir dataDir = QDir(globalSettings->get("FTBRoot").toString()); | ||||
| 	if (!dataDir.exists()) | ||||
| 	{ | ||||
| 		qDebug() << "The FTB directory specified does not exist. Please check your settings"; | ||||
| 		return records; | ||||
| 	} | ||||
| 	else if (!dir.exists()) | ||||
| 	{ | ||||
| 		qDebug() << "The FTB launcher data directory specified does not exist. Please check " | ||||
| 					"your settings"; | ||||
| 		return records; | ||||
| 	} | ||||
| 	dir.cd("ModPacks"); | ||||
| 	auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name); | ||||
| 	for (auto filename : allFiles) | ||||
| 	{ | ||||
| 		if (!filename.endsWith(".xml")) | ||||
| 			continue; | ||||
| 		auto fpath = dir.absoluteFilePath(filename); | ||||
| 		QFile f(fpath); | ||||
| 		qDebug() << "Discovering FTB instances -- " << fpath; | ||||
| 		if (!f.open(QFile::ReadOnly)) | ||||
| 			continue; | ||||
|  | ||||
| 		// read the FTB packs XML. | ||||
| 		QXmlStreamReader reader(&f); | ||||
| 		while (!reader.atEnd()) | ||||
| 		{ | ||||
| 			switch (reader.readNext()) | ||||
| 			{ | ||||
| 			case QXmlStreamReader::StartElement: | ||||
| 			{ | ||||
| 				if (reader.name() == "modpack") | ||||
| 				{ | ||||
| 					QXmlStreamAttributes attrs = reader.attributes(); | ||||
| 					FTBRecord record; | ||||
| 					record.dirName = attrs.value("dir").toString(); | ||||
| 					record.instanceDir = dataDir.absoluteFilePath(record.dirName); | ||||
| 					record.templateDir = dir.absoluteFilePath(record.dirName); | ||||
| 					QDir test(record.instanceDir); | ||||
| 					qDebug() << dataDir.absolutePath() << record.instanceDir << record.dirName; | ||||
| 					if (!test.exists()) | ||||
| 						continue; | ||||
| 					record.name = attrs.value("name").toString(); | ||||
| 					record.logo = attrs.value("logo").toString(); | ||||
| 					QString logo = record.logo; | ||||
| 					record.iconKey = logo.remove(QRegularExpression("\\..*")); | ||||
| 					auto customVersions = attrs.value("customMCVersions"); | ||||
| 					if (!customVersions.isNull()) | ||||
| 					{ | ||||
| 						QMap<QString, QString> versionMatcher; | ||||
| 						QString customVersionsStr = customVersions.toString(); | ||||
| 						QStringList list = customVersionsStr.split(';'); | ||||
| 						for (auto item : list) | ||||
| 						{ | ||||
| 							auto segment = item.split('^'); | ||||
| 							if (segment.size() != 2) | ||||
| 							{ | ||||
| 								qCritical() << "FTB: Segment of size < 2 in " | ||||
| 											<< customVersionsStr; | ||||
| 								continue; | ||||
| 							} | ||||
| 							versionMatcher[segment[0]] = segment[1]; | ||||
| 						} | ||||
| 						auto actualVersion = attrs.value("version").toString(); | ||||
| 						if (versionMatcher.contains(actualVersion)) | ||||
| 						{ | ||||
| 							record.mcVersion = versionMatcher[actualVersion]; | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							record.mcVersion = attrs.value("mcVersion").toString(); | ||||
| 						} | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						record.mcVersion = attrs.value("mcVersion").toString(); | ||||
| 					} | ||||
| 					record.description = attrs.value("description").toString(); | ||||
| 					records.insert(record); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case QXmlStreamReader::EndElement: | ||||
| 				break; | ||||
| 			case QXmlStreamReader::Characters: | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		f.close(); | ||||
| 	} | ||||
| 	return records; | ||||
| } | ||||
|  | ||||
| InstancePtr loadInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record) | ||||
| { | ||||
| 	InstancePtr inst; | ||||
|  | ||||
| 	auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); | ||||
| 	m_settings->registerSetting("InstanceType", "Legacy"); | ||||
|  | ||||
| 	qDebug() << "Loading existing " << record.name; | ||||
|  | ||||
| 	QString inst_type = m_settings->get("InstanceType").toString(); | ||||
| 	if (inst_type == "LegacyFTB") | ||||
| 	{ | ||||
| 		inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir)); | ||||
| 	} | ||||
| 	else if (inst_type == "OneSixFTB") | ||||
| 	{ | ||||
| 		inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	qDebug() << "Construction " << record.instanceDir; | ||||
|  | ||||
| 	SettingsObject::Lock lock(inst->settings()); | ||||
| 	inst->init(); | ||||
| 	qDebug() << "Init " << record.instanceDir; | ||||
| 	inst->setGroupInitial("FTB"); | ||||
| 	/** | ||||
| 	 * FIXME: this does not respect the user's preferences. BUT, it would work nicely with the planned pack support | ||||
| 	 *        -> instead of changing the user values, change pack values (defaults you can look at and revert to) | ||||
| 	 */ | ||||
| 	/* | ||||
| 	inst->setName(record.name); | ||||
| 	inst->setIconKey(record.iconKey); | ||||
| 	inst->setNotes(record.description); | ||||
| 	*/ | ||||
| 	if (inst->intendedVersionId() != record.mcVersion) | ||||
| 	{ | ||||
| 		inst->setIntendedVersionId(record.mcVersion); | ||||
| 	} | ||||
| 	qDebug() << "Post-Process " << record.instanceDir; | ||||
| 	if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap)) | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	qDebug() << "Final " << record.instanceDir; | ||||
| 	return inst; | ||||
| } | ||||
|  | ||||
| InstancePtr createInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record) | ||||
| { | ||||
| 	QDir rootDir(record.instanceDir); | ||||
|  | ||||
| 	InstancePtr inst; | ||||
|  | ||||
| 	qDebug() << "Converting " << record.name << " as new."; | ||||
|  | ||||
| 	auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion)); | ||||
| 	if (!mcVersion) | ||||
| 	{ | ||||
| 		qCritical() << "Can't load instance " << record.instanceDir | ||||
| 					<< " because minecraft version " << record.mcVersion | ||||
| 					<< " can't be resolved."; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	if (!rootDir.exists() && !rootDir.mkpath(".")) | ||||
| 	{ | ||||
| 		qCritical() << "Can't create instance folder" << record.instanceDir; | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg")); | ||||
| 	m_settings->registerSetting("InstanceType", "Legacy"); | ||||
|  | ||||
| 	if (mcVersion->usesLegacyLauncher()) | ||||
| 	{ | ||||
| 		m_settings->set("InstanceType", "LegacyFTB"); | ||||
| 		inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		m_settings->set("InstanceType", "OneSixFTB"); | ||||
| 		inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir)); | ||||
| 	} | ||||
| 	// initialize | ||||
| 	{ | ||||
| 		SettingsObject::Lock lock(inst->settings()); | ||||
| 		inst->setIntendedVersionId(mcVersion->descriptor()); | ||||
| 		inst->init(); | ||||
| 		inst->setGroupInitial("FTB"); | ||||
| 		inst->setName(record.name); | ||||
| 		inst->setIconKey(record.iconKey); | ||||
| 		inst->setNotes(record.description); | ||||
| 		qDebug() << "Post-Process " << record.instanceDir; | ||||
| 		if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap)) | ||||
| 		{ | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 	} | ||||
| 	return inst; | ||||
| } | ||||
|  | ||||
| void FTBPlugin::loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList) | ||||
| { | ||||
| 	// nothing to load when we don't have | ||||
| 	if (globalSettings->get("TrackFTBInstances").toBool() != true) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	auto records = discoverFTBInstances(globalSettings); | ||||
| 	if (!records.size()) | ||||
| 	{ | ||||
| 		qDebug() << "No FTB instances to load."; | ||||
| 		return; | ||||
| 	} | ||||
| 	qDebug() << "Loading FTB instances! -- got " << records.size(); | ||||
| 	// process the records we acquired. | ||||
| 	for (auto record : records) | ||||
| 	{ | ||||
| 		qDebug() << "Loading FTB instance from " << record.instanceDir; | ||||
| 		QString iconKey = record.iconKey; | ||||
| 		// MMC->icons()->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), MMCIcon::Transient); | ||||
| 		auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg"); | ||||
| 		qDebug() << "ICON get!"; | ||||
|  | ||||
| 		if (QFileInfo(settingsFilePath).exists()) | ||||
| 		{ | ||||
| 			auto instPtr = loadInstance(globalSettings, groupMap, record); | ||||
| 			if (!instPtr) | ||||
| 			{ | ||||
| 				qWarning() << "Couldn't load instance config:" << settingsFilePath; | ||||
| 				if(!QFile::remove(settingsFilePath)) | ||||
| 				{ | ||||
| 					qWarning() << "Couldn't remove broken instance config!"; | ||||
| 					continue; | ||||
| 				} | ||||
| 				// failed to load, but removed the poisonous file | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				tempList.append(InstancePtr(instPtr)); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 		auto instPtr = createInstance(globalSettings, groupMap, record); | ||||
| 		if (!instPtr) | ||||
| 		{ | ||||
| 			qWarning() << "Couldn't create FTB instance!"; | ||||
| 			continue; | ||||
| 		} | ||||
| 		tempList.append(InstancePtr(instPtr)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #ifdef Q_OS_WIN32 | ||||
| #include <windows.h> | ||||
| static const int APPDATA_BUFFER_SIZE = 1024; | ||||
| #endif | ||||
|  | ||||
| static QString getLocalCacheStorageLocation() | ||||
| { | ||||
| 	QString ftbDefault; | ||||
| #ifdef Q_OS_WIN32 | ||||
| 	wchar_t buf[APPDATA_BUFFER_SIZE]; | ||||
| 	if (GetEnvironmentVariableW(L"LOCALAPPDATA", buf, APPDATA_BUFFER_SIZE)) // local | ||||
| 	{ | ||||
| 		ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher"); | ||||
| 	} | ||||
| 	else if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE)) // roaming | ||||
| 	{ | ||||
| 		ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		qCritical() << "Your LOCALAPPDATA and APPDATA folders are missing!" | ||||
| 			" If you are on windows, this means your system is broken."; | ||||
| 	} | ||||
| #elif defined(Q_OS_MAC) | ||||
| 	ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher"); | ||||
| #else | ||||
| 	ftbDefault = QDir::home().absoluteFilePath(".ftblauncher"); | ||||
| #endif | ||||
| 	return ftbDefault; | ||||
| } | ||||
|  | ||||
|  | ||||
| static QString getRoamingStorageLocation() | ||||
| { | ||||
| 	QString ftbDefault; | ||||
| #ifdef Q_OS_WIN32 | ||||
| 	wchar_t buf[APPDATA_BUFFER_SIZE]; | ||||
| 	QString cacheStorage; | ||||
| 	if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE)) | ||||
| 	{ | ||||
| 		ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		qCritical() << "Your APPDATA folder is missing! If you are on windows, this means your system is broken."; | ||||
| 	} | ||||
| #elif defined(Q_OS_MAC) | ||||
| 	ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher"); | ||||
| #else | ||||
| 	ftbDefault = QDir::home().absoluteFilePath(".ftblauncher"); | ||||
| #endif | ||||
| 	return ftbDefault; | ||||
| } | ||||
|  | ||||
| void FTBPlugin::initialize(SettingsObjectPtr globalSettings) | ||||
| { | ||||
| 	// FTB | ||||
| 	globalSettings->registerSetting("TrackFTBInstances", false); | ||||
| 	QString ftbRoaming = getRoamingStorageLocation(); | ||||
| 	QString ftbLocal = getLocalCacheStorageLocation(); | ||||
|  | ||||
| 	globalSettings->registerSetting("FTBLauncherRoaming", ftbRoaming); | ||||
| 	globalSettings->registerSetting("FTBLauncherLocal", ftbLocal); | ||||
| 	qDebug() << "FTB Launcher paths:" << globalSettings->get("FTBLauncherRoaming").toString() | ||||
| 			 << "and" << globalSettings->get("FTBLauncherLocal").toString(); | ||||
|  | ||||
| 	globalSettings->registerSetting("FTBRoot"); | ||||
| 	if (globalSettings->get("FTBRoot").isNull()) | ||||
| 	{ | ||||
| 		QString ftbRoot; | ||||
| 		QFile f(QDir(globalSettings->get("FTBLauncherRoaming").toString()).absoluteFilePath("ftblaunch.cfg")); | ||||
| 		qDebug() << "Attempting to read" << f.fileName(); | ||||
| 		if (f.open(QFile::ReadOnly)) | ||||
| 		{ | ||||
| 			const QString data = QString::fromLatin1(f.readAll()); | ||||
| 			QRegularExpression exp("installPath=(.*)"); | ||||
| 			ftbRoot = QDir::cleanPath(exp.match(data).captured(1)); | ||||
| #ifdef Q_OS_WIN32 | ||||
| 			if (!ftbRoot.isEmpty()) | ||||
| 			{ | ||||
| 				if (ftbRoot.at(0).isLetter() && ftbRoot.size() > 1 && ftbRoot.at(1) == '/') | ||||
| 				{ | ||||
| 					ftbRoot.remove(1, 1); | ||||
| 				} | ||||
| 			} | ||||
| #endif | ||||
| 			if (ftbRoot.isEmpty()) | ||||
| 			{ | ||||
| 				qDebug() << "Failed to get FTB root path"; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				qDebug() << "FTB is installed at" << ftbRoot; | ||||
| 				globalSettings->set("FTBRoot", ftbRoot); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			qWarning() << "Couldn't open" << f.fileName() << ":" << f.errorString(); | ||||
| 			qWarning() << "This is perfectly normal if you don't have FTB installed"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										13
									
								
								api/logic/minecraft/ftb/FTBPlugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								api/logic/minecraft/ftb/FTBPlugin.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <BaseInstance.h> | ||||
|  | ||||
| #include "multimc_logic_export.h" | ||||
|  | ||||
| // Pseudo-plugin for FTB related things. Super derpy! | ||||
| class MULTIMC_LOGIC_EXPORT FTBPlugin | ||||
| { | ||||
| public: | ||||
| 	static void initialize(SettingsObjectPtr globalSettings); | ||||
| 	static void loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList); | ||||
| }; | ||||
							
								
								
									
										128
									
								
								api/logic/minecraft/ftb/FTBProfileStrategy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								api/logic/minecraft/ftb/FTBProfileStrategy.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| #include "FTBProfileStrategy.h" | ||||
| #include "OneSixFTBInstance.h" | ||||
|  | ||||
| #include "minecraft/VersionBuildError.h" | ||||
| #include "minecraft/MinecraftVersionList.h" | ||||
| #include <FileSystem.h> | ||||
|  | ||||
| #include <QDir> | ||||
| #include <QUuid> | ||||
| #include <QJsonDocument> | ||||
| #include <QJsonArray> | ||||
|  | ||||
| FTBProfileStrategy::FTBProfileStrategy(OneSixFTBInstance* instance) : OneSixProfileStrategy(instance) | ||||
| { | ||||
| } | ||||
|  | ||||
| void FTBProfileStrategy::loadDefaultBuiltinPatches() | ||||
| { | ||||
| 	// FIXME: this should be here, but it needs us to be able to deal with multiple libraries paths | ||||
| 	// OneSixProfileStrategy::loadDefaultBuiltinPatches(); | ||||
| 	auto mcVersion = m_instance->intendedVersionId(); | ||||
| 	auto nativeInstance = dynamic_cast<OneSixFTBInstance *>(m_instance); | ||||
|  | ||||
| 	ProfilePatchPtr minecraftPatch; | ||||
| 	{ | ||||
| 		auto mcJson = m_instance->versionsPath().absoluteFilePath(mcVersion + "/" + mcVersion + ".json"); | ||||
| 		// load up the base minecraft patch | ||||
| 		if(QFile::exists(mcJson)) | ||||
| 		{ | ||||
| 			auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false); | ||||
| 			file->fileId = "net.minecraft"; | ||||
| 			file->name = QObject::tr("Minecraft (tracked)"); | ||||
| 			file->setVanilla(true); | ||||
| 			if(file->version.isEmpty()) | ||||
| 			{ | ||||
| 				file->version = mcVersion; | ||||
| 			} | ||||
| 			for(auto addLib: file->libraries) | ||||
| 			{ | ||||
| 				addLib->setHint("local"); | ||||
| 				addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath()); | ||||
| 			} | ||||
| 			minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			throw VersionIncomplete("net.minecraft"); | ||||
| 		} | ||||
| 		minecraftPatch->setOrder(-2); | ||||
| 	} | ||||
| 	profile->appendPatch(minecraftPatch); | ||||
|  | ||||
| 	ProfilePatchPtr packPatch; | ||||
| 	{ | ||||
| 		auto mcJson = m_instance->minecraftRoot() + "/pack.json"; | ||||
| 		// load up the base minecraft patch | ||||
| 		if(QFile::exists(mcJson)) | ||||
| 		{ | ||||
| 			auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false); | ||||
|  | ||||
| 			// adapt the loaded file - the FTB patch file format is different than ours. | ||||
| 			file->minecraftVersion.clear(); | ||||
| 			for(auto addLib: file->libraries) | ||||
| 			{ | ||||
| 				addLib->setHint("local"); | ||||
| 				addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath()); | ||||
| 			} | ||||
| 			file->fileId = "org.multimc.ftb.pack"; | ||||
| 			file->setVanilla(true); | ||||
| 			file->name = QObject::tr("%1 (FTB pack)").arg(m_instance->name()); | ||||
| 			if(file->version.isEmpty()) | ||||
| 			{ | ||||
| 				file->version = QObject::tr("Unknown"); | ||||
| 				QFile versionFile (FS::PathCombine(m_instance->instanceRoot(), "version")); | ||||
| 				if(versionFile.exists()) | ||||
| 				{ | ||||
| 					if(versionFile.open(QIODevice::ReadOnly)) | ||||
| 					{ | ||||
| 						// FIXME: just guessing the encoding/charset here. | ||||
| 						auto version = QString::fromUtf8(versionFile.readAll()); | ||||
| 						file->version = version; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			packPatch = std::dynamic_pointer_cast<ProfilePatch>(file); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			throw VersionIncomplete("org.multimc.ftb.pack"); | ||||
| 		} | ||||
| 		packPatch->setOrder(1); | ||||
| 	} | ||||
| 	profile->appendPatch(packPatch); | ||||
|  | ||||
| } | ||||
|  | ||||
| void FTBProfileStrategy::load() | ||||
| { | ||||
| 	profile->clearPatches(); | ||||
|  | ||||
| 	loadDefaultBuiltinPatches(); | ||||
| 	loadUserPatches(); | ||||
| } | ||||
|  | ||||
| bool FTBProfileStrategy::saveOrder(ProfileUtils::PatchOrder order) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool FTBProfileStrategy::resetOrder() | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool FTBProfileStrategy::installJarMods(QStringList filepaths) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool FTBProfileStrategy::customizePatch(ProfilePatchPtr patch) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool FTBProfileStrategy::revertPatch(ProfilePatchPtr patch) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
							
								
								
									
										21
									
								
								api/logic/minecraft/ftb/FTBProfileStrategy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								api/logic/minecraft/ftb/FTBProfileStrategy.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| #pragma once | ||||
| #include "minecraft/ProfileStrategy.h" | ||||
| #include "minecraft/onesix/OneSixProfileStrategy.h" | ||||
|  | ||||
| class OneSixFTBInstance; | ||||
|  | ||||
| class FTBProfileStrategy : public OneSixProfileStrategy | ||||
| { | ||||
| public: | ||||
| 	FTBProfileStrategy(OneSixFTBInstance * instance); | ||||
| 	virtual ~FTBProfileStrategy() {}; | ||||
| 	virtual void load() override; | ||||
| 	virtual bool resetOrder() override; | ||||
| 	virtual bool saveOrder(ProfileUtils::PatchOrder order) override; | ||||
| 	virtual bool installJarMods(QStringList filepaths) override; | ||||
| 	virtual bool customizePatch (ProfilePatchPtr patch) override; | ||||
| 	virtual bool revertPatch (ProfilePatchPtr patch) override; | ||||
|  | ||||
| protected: | ||||
| 	virtual void loadDefaultBuiltinPatches() override; | ||||
| }; | ||||
							
								
								
									
										32
									
								
								api/logic/minecraft/ftb/FTBVersion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								api/logic/minecraft/ftb/FTBVersion.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #pragma once | ||||
| #include <minecraft/MinecraftVersion.h> | ||||
|  | ||||
| class FTBVersion : public BaseVersion | ||||
| { | ||||
| public: | ||||
| 	FTBVersion(MinecraftVersionPtr parent) : m_version(parent){}; | ||||
|  | ||||
| public: | ||||
| 	virtual QString descriptor() override | ||||
| 	{ | ||||
| 		return m_version->descriptor(); | ||||
| 	} | ||||
|  | ||||
| 	virtual QString name() override | ||||
| 	{ | ||||
| 		return m_version->name(); | ||||
| 	} | ||||
|  | ||||
| 	virtual QString typeString() const override | ||||
| 	{ | ||||
| 		return m_version->typeString(); | ||||
| 	} | ||||
|  | ||||
| 	MinecraftVersionPtr getMinecraftVersion() | ||||
| 	{ | ||||
| 		return m_version; | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| 	MinecraftVersionPtr m_version; | ||||
| }; | ||||
							
								
								
									
										27
									
								
								api/logic/minecraft/ftb/LegacyFTBInstance.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								api/logic/minecraft/ftb/LegacyFTBInstance.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include "LegacyFTBInstance.h" | ||||
| #include <settings/INISettingsObject.h> | ||||
| #include <QDir> | ||||
|  | ||||
| LegacyFTBInstance::LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) : | ||||
| 	LegacyInstance(globalSettings, settings, rootDir) | ||||
| { | ||||
| } | ||||
|  | ||||
| QString LegacyFTBInstance::id() const | ||||
| { | ||||
| 	return "FTB/" + BaseInstance::id(); | ||||
| } | ||||
|  | ||||
| void LegacyFTBInstance::copy(const QDir &newDir) | ||||
| { | ||||
| 	// set the target instance to be plain Legacy | ||||
| 	INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg")); | ||||
| 	settings_obj.registerSetting("InstanceType", "Legacy"); | ||||
| 	QString inst_type = settings_obj.get("InstanceType").toString(); | ||||
| 	settings_obj.set("InstanceType", "Legacy"); | ||||
| } | ||||
|  | ||||
| QString LegacyFTBInstance::typeName() const | ||||
| { | ||||
| 	return tr("Legacy FTB"); | ||||
| } | ||||
							
								
								
									
										17
									
								
								api/logic/minecraft/ftb/LegacyFTBInstance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								api/logic/minecraft/ftb/LegacyFTBInstance.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "minecraft/legacy/LegacyInstance.h" | ||||
|  | ||||
| class LegacyFTBInstance : public LegacyInstance | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	explicit LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); | ||||
| 	virtual QString id() const; | ||||
| 	virtual void copy(const QDir &newDir); | ||||
| 	virtual QString typeName() const; | ||||
| 	bool canExport() const override | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| }; | ||||
							
								
								
									
										138
									
								
								api/logic/minecraft/ftb/OneSixFTBInstance.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								api/logic/minecraft/ftb/OneSixFTBInstance.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| #include "OneSixFTBInstance.h" | ||||
| #include "FTBProfileStrategy.h" | ||||
|  | ||||
| #include "minecraft/MinecraftProfile.h" | ||||
| #include "minecraft/GradleSpecifier.h" | ||||
| #include "tasks/SequentialTask.h" | ||||
| #include <settings/INISettingsObject.h> | ||||
| #include <FileSystem.h> | ||||
|  | ||||
| #include <QJsonArray> | ||||
|  | ||||
| OneSixFTBInstance::OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) : | ||||
| 	OneSixInstance(globalSettings, settings, rootDir) | ||||
| { | ||||
| 	m_globalSettings = globalSettings; | ||||
| } | ||||
|  | ||||
| void OneSixFTBInstance::copy(const QDir &newDir) | ||||
| { | ||||
| 	QStringList libraryNames; | ||||
| 	// create patch file | ||||
| 	{ | ||||
| 		qDebug()<< "Creating patch file for FTB instance..."; | ||||
| 		QFile f(minecraftRoot() + "/pack.json"); | ||||
| 		if (!f.open(QFile::ReadOnly)) | ||||
| 		{ | ||||
| 			qCritical() << "Couldn't open" << f.fileName() << ":" << f.errorString(); | ||||
| 			return; | ||||
| 		} | ||||
| 		QJsonObject root = QJsonDocument::fromJson(f.readAll()).object(); | ||||
| 		QJsonArray libs = root.value("libraries").toArray(); | ||||
| 		QJsonArray outLibs; | ||||
| 		for (auto lib : libs) | ||||
| 		{ | ||||
| 			QJsonObject libObj = lib.toObject(); | ||||
| 			libObj.insert("MMC-hint", QString("local")); | ||||
| 			libObj.insert("insert", QString("prepend")); | ||||
| 			libraryNames.append(libObj.value("name").toString()); | ||||
| 			outLibs.append(libObj); | ||||
| 		} | ||||
| 		root.remove("libraries"); | ||||
| 		root.remove("id"); | ||||
|  | ||||
| 		// HACK HACK HACK HACK | ||||
| 		// A workaround for a problem in MultiMC, triggered by a historical problem in FTB, | ||||
| 		// triggered by Mojang getting their library versions wrong in 1.7.10 | ||||
| 		if(intendedVersionId() == "1.7.10") | ||||
| 		{ | ||||
| 			auto insert = [&outLibs, &libraryNames](QString name) | ||||
| 			{ | ||||
| 				QJsonObject libObj; | ||||
| 				libObj.insert("insert", QString("replace")); | ||||
| 				libObj.insert("name", name); | ||||
| 				libraryNames.push_back(name); | ||||
| 				outLibs.prepend(libObj); | ||||
| 			}; | ||||
| 			insert("com.google.guava:guava:16.0"); | ||||
| 			insert("org.apache.commons:commons-lang3:3.2.1"); | ||||
| 		} | ||||
| 		root.insert("+libraries", outLibs); | ||||
| 		root.insert("order", 1); | ||||
| 		root.insert("fileId", QString("org.multimc.ftb.pack.json")); | ||||
| 		root.insert("name", name()); | ||||
| 		root.insert("mcVersion", intendedVersionId()); | ||||
| 		root.insert("version", intendedVersionId()); | ||||
| 		FS::ensureFilePathExists(newDir.absoluteFilePath("patches/ftb.json")); | ||||
| 		QFile out(newDir.absoluteFilePath("patches/ftb.json")); | ||||
| 		if (!out.open(QFile::WriteOnly | QFile::Truncate)) | ||||
| 		{ | ||||
| 			qCritical() << "Couldn't open" << out.fileName() << ":" << out.errorString(); | ||||
| 			return; | ||||
| 		} | ||||
| 		out.write(QJsonDocument(root).toJson()); | ||||
| 	} | ||||
| 	// copy libraries | ||||
| 	{ | ||||
| 		qDebug() << "Copying FTB libraries"; | ||||
| 		for (auto library : libraryNames) | ||||
| 		{ | ||||
| 			GradleSpecifier lib(library); | ||||
| 			const QString out = QDir::current().absoluteFilePath("libraries/" + lib.toPath()); | ||||
| 			if (QFile::exists(out)) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (!FS::ensureFilePathExists(out)) | ||||
| 			{ | ||||
| 				qCritical() << "Couldn't create folder structure for" << out; | ||||
| 			} | ||||
| 			if (!QFile::copy(librariesPath().absoluteFilePath(lib.toPath()), out)) | ||||
| 			{ | ||||
| 				qCritical() << "Couldn't copy" << QString(lib); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	// now set the target instance to be plain OneSix | ||||
| 	INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg")); | ||||
| 	settings_obj.registerSetting("InstanceType", "Legacy"); | ||||
| 	QString inst_type = settings_obj.get("InstanceType").toString(); | ||||
| 	settings_obj.set("InstanceType", "OneSix"); | ||||
| } | ||||
|  | ||||
| QString OneSixFTBInstance::id() const | ||||
| { | ||||
| 	return "FTB/" + BaseInstance::id(); | ||||
| } | ||||
|  | ||||
| QDir OneSixFTBInstance::librariesPath() const | ||||
| { | ||||
| 	return QDir(m_globalSettings->get("FTBRoot").toString() + "/libraries"); | ||||
| } | ||||
|  | ||||
| QDir OneSixFTBInstance::versionsPath() const | ||||
| { | ||||
| 	return QDir(m_globalSettings->get("FTBRoot").toString() + "/versions"); | ||||
| } | ||||
|  | ||||
| bool OneSixFTBInstance::providesVersionFile() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void OneSixFTBInstance::createProfile() | ||||
| { | ||||
| 	m_profile.reset(new MinecraftProfile(new FTBProfileStrategy(this))); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Task> OneSixFTBInstance::createUpdateTask() | ||||
| { | ||||
| 	return OneSixInstance::createUpdateTask(); | ||||
| } | ||||
|  | ||||
| QString OneSixFTBInstance::typeName() const | ||||
| { | ||||
| 	return tr("OneSix FTB"); | ||||
| } | ||||
|  | ||||
| #include "OneSixFTBInstance.moc" | ||||
							
								
								
									
										30
									
								
								api/logic/minecraft/ftb/OneSixFTBInstance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								api/logic/minecraft/ftb/OneSixFTBInstance.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "minecraft/onesix/OneSixInstance.h" | ||||
|  | ||||
| class OneSixFTBInstance : public OneSixInstance | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	explicit OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); | ||||
|     virtual ~OneSixFTBInstance(){}; | ||||
|  | ||||
| 	void copy(const QDir &newDir) override; | ||||
|  | ||||
| 	virtual void createProfile() override; | ||||
|  | ||||
| 	virtual std::shared_ptr<Task> createUpdateTask() override; | ||||
|  | ||||
| 	virtual QString id() const override; | ||||
|  | ||||
| 	QDir librariesPath() const override; | ||||
| 	QDir versionsPath() const override; | ||||
| 	bool providesVersionFile() const override; | ||||
| 	virtual QString typeName() const override; | ||||
| 	bool canExport() const override | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| private: | ||||
| 	SettingsObjectPtr m_globalSettings; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user