summaryrefslogtreecommitdiffstats
path: root/logic/ForgeInstaller.cpp
blob: 00ad8d192e1290955599dbb983c548f1d99989e5 (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
#include "ForgeInstaller.h"
#include "OneSixVersion.h"
#include "OneSixLibrary.h"
#include <quazip.h>
#include <quazipfile.h>
#include <pathutils.h>
#include <QStringList>

ForgeInstaller::ForgeInstaller(QString filename, QString universal_url)
{
	QSharedPointer<OneSixVersion> newVersion;
	m_universal_url = universal_url;

	QuaZip zip(filename);
	if (!zip.open(QuaZip::mdUnzip))
		return;

	QuaZipFile file(&zip);

	// read the install profile
	if (!zip.setCurrentFile("install_profile.json"))
		return;

	QJsonParseError jsonError;
	if (!file.open(QIODevice::ReadOnly))
		return;
	QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError);
	file.close();
	if (jsonError.error != QJsonParseError::NoError)
		return;

	if (!jsonDoc.isObject())
		return;

	QJsonObject root = jsonDoc.object();

	auto installVal = root.value("install");
	auto versionInfoVal = root.value("versionInfo");
	if (!installVal.isObject() || !versionInfoVal.isObject())
		return;

	// read the forge version info
	{
		newVersion = OneSixVersion::fromJson(versionInfoVal.toObject());
		if (!newVersion)
			return;
	}

	QJsonObject installObj = installVal.toObject();
	QString libraryName = installObj.value("path").toString();
	internalPath = installObj.value("filePath").toString();

	// where do we put the library? decode the mojang path
	OneSixLibrary lib(libraryName);
	lib.finalize();
	finalPath = "libraries/" + lib.storagePath();
	if (!ensureFilePathExists(finalPath))
		return;

	if (!zip.setCurrentFile(internalPath))
		return;
	if (!file.open(QIODevice::ReadOnly))
		return;
	{
		QByteArray data = file.readAll();
		// extract file
		QSaveFile extraction(finalPath);
		if (!extraction.open(QIODevice::WriteOnly))
			return;
		if (extraction.write(data) != data.size())
			return;
		if (!extraction.commit())
			return;
	}
	file.close();

	m_forge_version = newVersion;
	realVersionId = m_forge_version->id = installObj.value("minecraft").toString();
}

bool ForgeInstaller::apply(QSharedPointer<OneSixVersion> to)
{
	if (!m_forge_version)
		return false;
	to->externalUpdateStart();
	int sliding_insert_window = 0;
	{
		// for each library in the version we are adding (except for the blacklisted)
		QSet<QString> blacklist{"lwjgl", "lwjgl_util", "lwjgl-platform"};
		for (auto lib : m_forge_version->libraries)
		{
			QString libName = lib->name();
			// if this is the actual forge lib, set an absolute url for the download
			if(libName.contains("minecraftforge"))
			{
				lib->setAbsoluteUrl(m_universal_url);
			}
			if (blacklist.contains(libName))
				continue;

			// find an entry that matches this one
			bool found = false;
			for (auto tolib : to->libraries)
			{
				if (tolib->name() != libName)
					continue;
				found = true;
				// replace lib
				tolib = lib;
				break;
			}
			if (!found)
			{
				// add lib
				to->libraries.insert(sliding_insert_window, lib);
				sliding_insert_window++;
			}
		}
		to->mainClass = m_forge_version->mainClass;
		to->minecraftArguments = m_forge_version->minecraftArguments;
		to->processArguments = m_forge_version->processArguments;
	}
	to->externalUpdateFinish();
	return to->toOriginalFile();
}