summaryrefslogtreecommitdiffstats
path: root/api/logic/java/launch/CheckJava.cpp
blob: 24f26682d1de59bfe21af619f42bb7f66fcca56b (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
/* Copyright 2013-2018 MultiMC Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "CheckJava.h"
#include <launch/LaunchTask.h>
#include <FileSystem.h>
#include <QStandardPaths>
#include <QFileInfo>
#include <sys.h>

void CheckJava::executeTask()
{
	auto instance = m_parent->instance();
	auto settings = instance->settings();
	m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString());
	bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();

	auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
	if (realJavaPath.isEmpty())
	{
		if (perInstance)
		{
			emit logLine(
				tr("The java binary \"%1\" couldn't be found. Please fix the java path "
				   "override in the instance's settings or disable it.").arg(m_javaPath),
				MessageLevel::Warning);
		}
		else
		{
			emit logLine(tr("The java binary \"%1\" couldn't be found. Please set up java in "
							"the settings.").arg(m_javaPath),
						 MessageLevel::Warning);
		}
		emitFailed(tr("Java path is not valid."));
		return;
	}
	else
	{
		emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::MultiMC);
	}

	QFileInfo javaInfo(realJavaPath);
	qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
	auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
	auto storedArchitecture = settings->get("JavaArchitecture").toString();
	auto storedVersion = settings->get("JavaVersion").toString();
	m_javaUnixTime = javaUnixTime;
	// if timestamps are not the same, or something is missing, check!
	if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
	{
		m_JavaChecker = std::make_shared<JavaChecker>();
		emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
		connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
		m_JavaChecker->m_path = realJavaPath;
		m_JavaChecker->performCheck();
		return;
	}
	else
	{
		auto verString = instance->settings()->get("JavaVersion").toString();
		auto archString = instance->settings()->get("JavaArchitecture").toString();
		printJavaInfo(verString, archString);
	}
	emitSucceeded();
}

void CheckJava::checkJavaFinished(JavaCheckResult result)
{
	switch (result.validity)
	{
		case JavaCheckResult::Validity::Errored:
		{
			// Error message displayed if java can't start
			emit logLine(tr("Could not start java:"), MessageLevel::Error);
			emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
			emit logLine("\nCheck your MultiMC Java settings.", MessageLevel::MultiMC);
			printSystemInfo(false, false);
			emitFailed(tr("Could not start java!"));
			return;
		}
		case JavaCheckResult::Validity::ReturnedInvalidData:
		{
			emit logLine(tr("Java checker returned some invalid data MultiMC doesn't understand:"), MessageLevel::Error);
			emit logLines(result.outLog.split('\n'), MessageLevel::Warning);
			emit logLine("\nMinecraft might not start properly.", MessageLevel::MultiMC);
			printSystemInfo(false, false);
			emitSucceeded();
			return;
		}
		case JavaCheckResult::Validity::Valid:
		{
			auto instance = m_parent->instance();
			printJavaInfo(result.javaVersion.toString(), result.mojangPlatform);
			instance->settings()->set("JavaVersion", result.javaVersion.toString());
			instance->settings()->set("JavaArchitecture", result.mojangPlatform);
			instance->settings()->set("JavaTimestamp", m_javaUnixTime);
			emitSucceeded();
			return;
		}
	}
}

void CheckJava::printJavaInfo(const QString& version, const QString& architecture)
{
	emit logLine(tr("Java is version %1, using %2-bit architecture.\n\n").arg(version, architecture), MessageLevel::MultiMC);
	printSystemInfo(true, architecture == "64");
}

void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit)
{
	auto cpu64 = Sys::isCPU64bit();
	auto system64 = Sys::isSystem64bit();
	if(cpu64 != system64)
	{
		emit logLine(tr("Your CPU architecture is not matching your system architecture. You might want to install a 64bit Operating System.\n\n"), MessageLevel::Error);
	}
	if(javaIsKnown)
	{
		if(javaIs64bit != system64)
		{
			emit logLine(tr("Your Java architecture is not matching your system architecture. You might want to install a 64bit Java version.\n\n"), MessageLevel::Error);
		}
	}
}