summaryrefslogtreecommitdiffstats
path: root/logic/ftb/FTBProfileStrategy.cpp
blob: 20feba61b4f3c79e5cefed0ffc8a52a469288237 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include "logic/ftb/FTBProfileStrategy.h"
#include "logic/minecraft/VersionBuildError.h"
#include "logic/ftb/OneSixFTBInstance.h"
#include "logic/minecraft/MinecraftVersionList.h"

#include "MultiMC.h"

#include <pathutils.h>
#include <QDir>
#include <QUuid>
#include <QJsonDocument>
#include <QJsonArray>

FTBProfileStrategy::FTBProfileStrategy(OneSixFTBInstance* instance) : OneSixProfileStrategy(instance)
{
}

void FTBProfileStrategy::loadDefaultBuiltinPatches()
{
	auto mcVersion = m_instance->intendedVersionId();

	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)");
			if(file->version.isEmpty())
			{
				file->version = mcVersion;
			}
			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->addLibs = file->overwriteLibs;
			file->overwriteLibs.clear();
			file->shouldOverwriteLibs = false;
			file->id.clear();
			for(auto addLib: file->addLibs)
			{
				addLib->m_hint = "local";
				addLib->insertType = RawLibrary::Prepend;
			}
			file->fileId = "org.multimc.ftb.pack";
			file->name = QObject::tr("%1 (FTB pack)").arg(m_instance->name());
			if(file->version.isEmpty())
			{
				file->version = QObject::tr("Unknown");
				QFile versionFile (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;
					}
				}
			}
			minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
		}
		else
		{
			throw VersionIncomplete("org.multimc.ftb.pack");
		}
		minecraftPatch->setOrder(1);
	}
	profile->appendPatch(minecraftPatch);

}

void FTBProfileStrategy::loadUserPatches()
{
	// load all patches, put into map for ordering, apply in the right order
	ProfileUtils::PatchOrder userOrder;
	ProfileUtils::readOverrideOrders(PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
	QDir patches(PathCombine(m_instance->instanceRoot(),"patches"));

	// first, load things by sort order.
	for (auto id : userOrder)
	{
		// ignore builtins
		if (id == "net.minecraft")
			continue;
		if (id == "org.lwjgl")
			continue;
		// parse the file
		QString filename = patches.absoluteFilePath(id + ".json");
		QFileInfo finfo(filename);
		if(!finfo.exists())
		{
			QLOG_INFO() << "Patch file " << filename << " was deleted by external means...";
			continue;
		}
		QLOG_INFO() << "Reading" << filename << "by user order";
		auto file = ProfileUtils::parseJsonFile(finfo, false);
		// sanity check. prevent tampering with files.
		if (file->fileId != id)
		{
			throw VersionBuildError(
				QObject::tr("load id %1 does not match internal id %2").arg(id, file->fileId));
		}
		profile->appendPatch(file);
	}
	// now load the rest by internal preference.
	QMap<int, QPair<QString, VersionFilePtr>> files;
	for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files))
	{
		// parse the file
		QLOG_INFO() << "Reading" << info.fileName();
		auto file = ProfileUtils::parseJsonFile(info, true);
		// ignore builtins
		if (file->fileId == "net.minecraft")
			continue;
		if (file->fileId == "org.lwjgl")
			continue;
		// do not load what we already loaded in the first pass
		if (userOrder.contains(file->fileId))
			continue;
		if (files.contains(file->order))
		{
			// FIXME: do not throw?
			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));
	}
	for (auto order : files.keys())
	{
		auto &filePair = files[order];
		profile->appendPatch(filePair.second);
	}
}


void FTBProfileStrategy::load()
{
	profile->clearPatches();

	loadDefaultBuiltinPatches();
	loadUserPatches();

	profile->finalize();
}

bool FTBProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
{
	return false;
}

bool FTBProfileStrategy::resetOrder()
{
	return false;
}

bool FTBProfileStrategy::removePatch(ProfilePatchPtr patch)
{
	return false;
}

bool FTBProfileStrategy::installJarMods(QStringList filepaths)
{
	return false;
}