From 3b97e3c363711c96a0198fa57695eaaa021c82ba Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sat, 4 Jan 2014 11:49:06 +0100 Subject: Fix a few things related to the translations --- logic/NagUtils.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'logic') diff --git a/logic/NagUtils.cpp b/logic/NagUtils.cpp index 6f81b3c7..c963a98a 100644 --- a/logic/NagUtils.cpp +++ b/logic/NagUtils.cpp @@ -23,15 +23,15 @@ void checkJVMArgs(QString jvmargs, QWidget *parent) if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegExp("-Xm[sx]"))) { CustomMessageBox::selectable( - parent, parent->tr("JVM arguments warning"), - parent->tr("You tried to manually set a JVM memory option (using " - " \"-XX:PermSize\", \"-Xmx\" or \"-Xms\") - there" - " are dedicated boxes for these in the settings (Java" - " tab, in the Memory group at the top).\n" - "Your manual settings will be overridden by the" - " dedicated options.\n" - "This message will be displayed until you remove them" - " from the JVM arguments."), + parent, QObject::tr("JVM arguments warning"), + QObject::tr("You tried to manually set a JVM memory option (using " + " \"-XX:PermSize\", \"-Xmx\" or \"-Xms\") - there" + " are dedicated boxes for these in the settings (Java" + " tab, in the Memory group at the top).\n" + "Your manual settings will be overridden by the" + " dedicated options.\n" + "This message will be displayed until you remove them" + " from the JVM arguments."), QMessageBox::Warning)->exec(); } } -- cgit v1.2.3 From 7d76fd57e99e686d59f48038e7b762e4064996d1 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sun, 5 Jan 2014 23:24:19 +0100 Subject: Get rid of some obsolete functions --- logic/updater/UpdateChecker.cpp | 1 - logic/updater/UpdateChecker.h | 2 -- 2 files changed, 3 deletions(-) (limited to 'logic') diff --git a/logic/updater/UpdateChecker.cpp b/logic/updater/UpdateChecker.cpp index 489e7769..68d97db5 100644 --- a/logic/updater/UpdateChecker.cpp +++ b/logic/updater/UpdateChecker.cpp @@ -30,7 +30,6 @@ UpdateChecker::UpdateChecker() { - m_currentChannel = VERSION_CHANNEL; m_channelListUrl = CHANLIST_URL; m_updateChecking = false; m_chanListLoading = false; diff --git a/logic/updater/UpdateChecker.h b/logic/updater/UpdateChecker.h index 7840cedc..3b0ee28d 100644 --- a/logic/updater/UpdateChecker.h +++ b/logic/updater/UpdateChecker.h @@ -27,7 +27,6 @@ public: UpdateChecker(); void checkForUpdate(bool notifyNoUpdate); - void setCurrentChannel(const QString &channel) { m_currentChannel = channel; } void setChannelListUrl(const QString &url) { m_channelListUrl = url; } /*! @@ -83,7 +82,6 @@ private: QString m_repoUrl; QString m_channelListUrl; - QString m_currentChannel; QList m_channels; -- cgit v1.2.3 From c51a993ff741074ac88bbc901ebfad9da636eeaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 9 Jan 2014 01:20:24 +0100 Subject: Add logging calls to the java checker. --- logic/JavaChecker.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'logic') diff --git a/logic/JavaChecker.cpp b/logic/JavaChecker.cpp index 6ee7b4cf..b87ee3d5 100644 --- a/logic/JavaChecker.cpp +++ b/logic/JavaChecker.cpp @@ -20,6 +20,9 @@ void JavaChecker::performCheck() process->setArguments(args); process->setProgram(path); process->setProcessChannelMode(QProcess::SeparateChannels); + QLOG_DEBUG() << "Running java checker!"; + QLOG_DEBUG() << "Java: " + path; + QLOG_DEBUG() << "Args: {" + args.join("|") + "}"; connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))); @@ -42,15 +45,19 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) result.path = path; result.id = id; } + QLOG_DEBUG() << "Java checker finished with status " << status << " exit code " << exitcode; if (status == QProcess::CrashExit || exitcode == 1) { + QLOG_DEBUG() << "Java checker failed!"; emit checkFinished(result); return; } bool success = true; QString p_stdout = _process->readAllStandardOutput(); + QLOG_DEBUG() << p_stdout; + QMap results; QStringList lines = p_stdout.split("\n", QString::SkipEmptyParts); for(QString line : lines) @@ -70,6 +77,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) if(!results.contains("os.arch") || !results.contains("java.version") || !success) { + QLOG_DEBUG() << "Java checker failed - couldn't extract required information."; emit checkFinished(result); return; } @@ -84,7 +92,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status) result.mojangPlatform = is_64 ? "64" : "32"; result.realPlatform = os_arch; result.javaVersion = java_version; - + QLOG_DEBUG() << "Java checker succeeded."; emit checkFinished(result); } @@ -93,7 +101,7 @@ void JavaChecker::error(QProcess::ProcessError err) if(err == QProcess::FailedToStart) { killTimer.stop(); - + QLOG_DEBUG() << "Java checker has failed to start."; JavaCheckResult result; { result.path = path; @@ -110,6 +118,7 @@ void JavaChecker::timeout() // NO MERCY. NO ABUSE. if(process) { + QLOG_DEBUG() << "Java checker has been killed by timeout."; process->kill(); } } -- cgit v1.2.3 From 3c189a65530a8bb67a86806861ca3abcd7c2da3b Mon Sep 17 00:00:00 2001 From: Sky Date: Fri, 10 Jan 2014 12:40:20 +0000 Subject: Hide user properties in the console too --- logic/MinecraftProcess.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'logic') diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 209929b7..b3959db9 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -90,6 +90,14 @@ QString MinecraftProcess::censorPrivateInfo(QString in) in.replace(profileId, ""); in.replace(profileName, ""); } + + auto i = m_account->user().properties.begin(); + while (i != m_account->user().properties.end()) + { + in.replace(i.value(), "<" + i.key().toUpper() + ">"); + ++i; + } + return in; } -- cgit v1.2.3 From 8e286c2b5c432e972df2e94b01481bbe094e464c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 10 Jan 2014 22:08:00 +0100 Subject: Make CacheDownload use QSaveFile --- logic/net/CacheDownload.cpp | 48 ++++++++++++++++++++------------------------- logic/net/CacheDownload.h | 6 +++--- 2 files changed, 24 insertions(+), 30 deletions(-) (limited to 'logic') diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 6eadae39..17fd7f2a 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -42,6 +42,13 @@ void CacheDownload::start() // if there already is a file and md5 checking is in effect and it can be opened if (!ensureFilePathExists(m_target_path)) { + QLOG_ERROR() << "Could not create folder for " + m_target_path; + emit failed(m_index_within_job); + return; + } + if(!m_output_file.open(QIODevice::WriteOnly)) + { + QLOG_ERROR() << "Could not open " + m_target_path + " for writing"; emit failed(m_index_within_job); return; } @@ -85,26 +92,21 @@ void CacheDownload::downloadFinished() // if the download succeeded if (m_status != Job_Failed) { - // nothing went wrong... m_status = Job_Finished; - if (m_output_file.isOpen()) + if (m_output_file.commit()) { - // save the data to the downloadable if we aren't saving to file - m_output_file.close(); m_entry->md5sum = md5sum.result().toHex().constData(); } else { - if (m_output_file.open(QIODevice::ReadOnly)) - { - m_entry->md5sum = - QCryptographicHash::hash(m_output_file.readAll(), QCryptographicHash::Md5) - .toHex() - .constData(); - m_output_file.close(); - } + QLOG_ERROR() << "Failed to commit changes to " << m_target_path; + m_output_file.cancelWriting(); + m_reply.reset(); + emit failed(m_index_within_job); + return; } + QFileInfo output_file_info(m_target_path); m_entry->etag = m_reply->rawHeader("ETag").constData(); @@ -124,8 +126,7 @@ void CacheDownload::downloadFinished() // else the download failed else { - m_output_file.close(); - m_output_file.remove(); + m_output_file.cancelWriting(); m_reply.reset(); emit failed(m_index_within_job); return; @@ -134,19 +135,12 @@ void CacheDownload::downloadFinished() void CacheDownload::downloadReadyRead() { - if (!m_output_file.isOpen()) - { - if (!m_output_file.open(QIODevice::WriteOnly)) - { - /* - * Can't open the file... the job failed - */ - m_reply->abort(); - emit failed(m_index_within_job); - return; - } - } QByteArray ba = m_reply->readAll(); md5sum.addData(ba); - m_output_file.write(ba); + if(m_output_file.write(ba) != ba.size()) + { + QLOG_ERROR() << "Failed writing into " + m_target_path; + m_reply->abort(); + emit failed(m_index_within_job); + } } diff --git a/logic/net/CacheDownload.h b/logic/net/CacheDownload.h index e25aecd2..921e231b 100644 --- a/logic/net/CacheDownload.h +++ b/logic/net/CacheDownload.h @@ -17,8 +17,8 @@ #include "NetAction.h" #include "HttpMetaCache.h" -#include -#include +#include +#include typedef std::shared_ptr CacheDownloadPtr; class CacheDownload : public NetAction @@ -29,7 +29,7 @@ public: /// if saving to file, use the one specified in this string QString m_target_path; /// this is the output file, if any - QFile m_output_file; + QSaveFile m_output_file; /// the hash-as-you-download QCryptographicHash md5sum; -- cgit v1.2.3 From 43a39a3bfbffa2997cf8ca5126ee3ac5157f62c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 11 Jan 2014 02:06:22 +0100 Subject: Harden CacheDownload. It's now super hard. SRSLY. --- logic/net/CacheDownload.cpp | 62 +++++++++++++++++++++++++++------------------ logic/net/CacheDownload.h | 2 ++ 2 files changed, 39 insertions(+), 25 deletions(-) (limited to 'logic') diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 17fd7f2a..8a8d00f0 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -33,8 +33,10 @@ CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry) void CacheDownload::start() { + m_status = Job_InProgress; if (!m_entry->stale) { + m_status = Job_Finished; emit succeeded(m_index_within_job); return; } @@ -43,12 +45,14 @@ void CacheDownload::start() if (!ensureFilePathExists(m_target_path)) { QLOG_ERROR() << "Could not create folder for " + m_target_path; + m_status = Job_Failed; emit failed(m_index_within_job); return; } - if(!m_output_file.open(QIODevice::WriteOnly)) + if (!m_output_file.open(QIODevice::WriteOnly)) { QLOG_ERROR() << "Could not open " + m_target_path + " for writing"; + m_status = Job_Failed; emit failed(m_index_within_job); return; } @@ -90,12 +94,21 @@ void CacheDownload::downloadError(QNetworkReply::NetworkError error) void CacheDownload::downloadFinished() { // if the download succeeded - if (m_status != Job_Failed) + if (m_status == Job_Failed) + { + m_output_file.cancelWriting(); + m_reply.reset(); + m_status = Job_Failed; + emit failed(m_index_within_job); + return; + } + + if (wroteAnyData) { // nothing went wrong... - m_status = Job_Finished; if (m_output_file.commit()) { + m_status = Job_Finished; m_entry->md5sum = md5sum.result().toHex().constData(); } else @@ -103,44 +116,43 @@ void CacheDownload::downloadFinished() QLOG_ERROR() << "Failed to commit changes to " << m_target_path; m_output_file.cancelWriting(); m_reply.reset(); + m_status = Job_Failed; emit failed(m_index_within_job); return; } - - QFileInfo output_file_info(m_target_path); - - m_entry->etag = m_reply->rawHeader("ETag").constData(); - if (m_reply->hasRawHeader("Last-Modified")) - { - m_entry->remote_changed_timestamp = m_reply->rawHeader("Last-Modified").constData(); - } - m_entry->local_changed_timestamp = - output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); - m_entry->stale = false; - MMC->metacache()->updateEntry(m_entry); - - m_reply.reset(); - emit succeeded(m_index_within_job); - return; } - // else the download failed else { - m_output_file.cancelWriting(); - m_reply.reset(); - emit failed(m_index_within_job); - return; + m_status = Job_Finished; + } + + QFileInfo output_file_info(m_target_path); + + m_entry->etag = m_reply->rawHeader("ETag").constData(); + if (m_reply->hasRawHeader("Last-Modified")) + { + m_entry->remote_changed_timestamp = m_reply->rawHeader("Last-Modified").constData(); } + m_entry->local_changed_timestamp = + output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); + m_entry->stale = false; + MMC->metacache()->updateEntry(m_entry); + + m_reply.reset(); + emit succeeded(m_index_within_job); + return; } void CacheDownload::downloadReadyRead() { QByteArray ba = m_reply->readAll(); md5sum.addData(ba); - if(m_output_file.write(ba) != ba.size()) + if (m_output_file.write(ba) != ba.size()) { QLOG_ERROR() << "Failed writing into " + m_target_path; + m_status = Job_Failed; m_reply->abort(); emit failed(m_index_within_job); } + wroteAnyData = true; } diff --git a/logic/net/CacheDownload.h b/logic/net/CacheDownload.h index 921e231b..48be1dae 100644 --- a/logic/net/CacheDownload.h +++ b/logic/net/CacheDownload.h @@ -33,6 +33,8 @@ public: /// the hash-as-you-download QCryptographicHash md5sum; + bool wroteAnyData = false; + public: explicit CacheDownload(QUrl url, MetaEntryPtr entry); static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry) -- cgit v1.2.3 From a774b3d24816aa0010e1d5f67b20acb99e7181ac Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 12 Jan 2014 18:28:42 +0000 Subject: Show Mojang service statuses in status bar --- logic/net/URLConstants.h | 2 + logic/status/StatusChecker.cpp | 138 +++++++++++++++++++++++++++++++++++++++++ logic/status/StatusChecker.h | 67 ++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 logic/status/StatusChecker.cpp create mode 100644 logic/status/StatusChecker.h (limited to 'logic') diff --git a/logic/net/URLConstants.h b/logic/net/URLConstants.h index 9579198d..8cb1f3fd 100644 --- a/logic/net/URLConstants.h +++ b/logic/net/URLConstants.h @@ -31,4 +31,6 @@ const QString SKINS_BASE("skins.minecraft.net/MinecraftSkins/"); const QString AUTH_BASE("authserver.mojang.com/"); const QString FORGE_LEGACY_URL("http://files.minecraftforge.net/minecraftforge/json"); const QString FORGE_GRADLE_URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/json"); +const QString MOJANG_STATUS_URL("http://status.mojang.com/check"); +const QString MOJANG_STATUS_NEWS_URL("http://status.mojang.com/news"); } diff --git a/logic/status/StatusChecker.cpp b/logic/status/StatusChecker.cpp new file mode 100644 index 00000000..54cf077a --- /dev/null +++ b/logic/status/StatusChecker.cpp @@ -0,0 +1,138 @@ +/* Copyright 2013 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 "StatusChecker.h" + +#include + +#include +#include + +#include + +StatusChecker::StatusChecker() +{ + +} + +void StatusChecker::reloadStatus() +{ + if (isLoadingStatus()) + { + QLOG_INFO() << "Ignored request to reload status. Currently reloading already."; + return; + } + + QLOG_INFO() << "Reloading status."; + + NetJob* job = new NetJob("Status JSON"); + job->addNetAction(ByteArrayDownload::make(URLConstants::MOJANG_STATUS_URL)); + QObject::connect(job, &NetJob::succeeded, this, &StatusChecker::statusDownloadFinished); + QObject::connect(job, &NetJob::failed, this, &StatusChecker::statusDownloadFailed); + m_statusNetJob.reset(job); + job->start(); +} + +void StatusChecker::statusDownloadFinished() +{ + // Parse the XML file and process the RSS feed entries. + QLOG_DEBUG() << "Finished loading status JSON."; + + QByteArray data; + { + ByteArrayDownloadPtr dl = std::dynamic_pointer_cast(m_statusNetJob->first()); + data = dl->m_data; + m_statusNetJob.reset(); + } + + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + + if (jsonError.error != QJsonParseError::NoError) + { + fail("Error parsing status JSON:" + jsonError.errorString()); + return; + } + + if (!jsonDoc.isArray()) + { + fail("Error parsing status JSON: JSON root is not an array"); + return; + } + + QJsonArray root = jsonDoc.array(); + + for(auto status = root.begin(); status != root.end(); ++status) + { + QVariantMap map = (*status).toObject().toVariantMap(); + + for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) + { + QString key = iter.key(); + QVariant value = iter.value(); + + if(value.type() == QVariant::Type::String) + { + m_statusEntries.insert(key, value.toString()); + QLOG_DEBUG() << "Status JSON object: " << key << m_statusEntries[key]; + } + else + { + fail("Malformed status JSON: expected status type to be a string."); + return; + } + } + } + + succeed(); +} + +void StatusChecker::statusDownloadFailed() +{ + fail("Failed to load status JSON."); +} + + +QMap StatusChecker::getStatusEntries() const +{ + return m_statusEntries; +} + +bool StatusChecker::isLoadingStatus() const +{ + return m_statusNetJob.get() != nullptr; +} + +QString StatusChecker::getLastLoadErrorMsg() const +{ + return m_lastLoadError; +} + +void StatusChecker::succeed() +{ + m_lastLoadError = ""; + QLOG_DEBUG() << "Status loading succeeded."; + m_statusNetJob.reset(); + emit statusLoaded(); +} + +void StatusChecker::fail(const QString& errorMsg) +{ + m_lastLoadError = errorMsg; + QLOG_DEBUG() << "Failed to load status:" << errorMsg; + m_statusNetJob.reset(); + emit statusLoadingFailed(errorMsg); +} + diff --git a/logic/status/StatusChecker.h b/logic/status/StatusChecker.h new file mode 100644 index 00000000..b81050ab --- /dev/null +++ b/logic/status/StatusChecker.h @@ -0,0 +1,67 @@ +/* Copyright 2013 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. + */ + +#pragma once + +#include +#include +#include + +#include + +class StatusChecker : public QObject +{ + Q_OBJECT +public: + StatusChecker(); + + QString getLastLoadErrorMsg() const; + + bool isStatusLoaded() const; + + bool isLoadingStatus() const; + + QMap getStatusEntries() const; + + void Q_SLOT reloadStatus(); + +signals: + void statusLoaded(); + void statusLoadingFailed(QString errorMsg); + +protected slots: + void statusDownloadFinished(); + void statusDownloadFailed(); + +protected: + QMap m_statusEntries; + NetJobPtr m_statusNetJob; + + //! True if news has been loaded. + bool m_loadedStatus; + + QString m_lastLoadError; + + /*! + * Emits newsLoaded() and sets m_lastLoadError to empty string. + */ + void Q_SLOT succeed(); + + /*! + * Emits newsLoadingFailed() and sets m_lastLoadError to the given message. + */ + void Q_SLOT fail(const QString& errorMsg); +}; + -- cgit v1.2.3 From c51090dcff68fc520a8377cb9ff5635a815ff489 Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 12 Jan 2014 18:34:43 +0000 Subject: Remove wrong comments --- logic/status/StatusChecker.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'logic') diff --git a/logic/status/StatusChecker.h b/logic/status/StatusChecker.h index b81050ab..1cb01836 100644 --- a/logic/status/StatusChecker.h +++ b/logic/status/StatusChecker.h @@ -48,20 +48,10 @@ protected slots: protected: QMap m_statusEntries; NetJobPtr m_statusNetJob; - - //! True if news has been loaded. bool m_loadedStatus; - QString m_lastLoadError; - /*! - * Emits newsLoaded() and sets m_lastLoadError to empty string. - */ void Q_SLOT succeed(); - - /*! - * Emits newsLoadingFailed() and sets m_lastLoadError to the given message. - */ void Q_SLOT fail(const QString& errorMsg); }; -- cgit v1.2.3 From 500581d095b634998f4d6db70276905cbfcf5d21 Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 12 Jan 2014 18:42:02 +0000 Subject: More comments removal --- logic/status/StatusChecker.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'logic') diff --git a/logic/status/StatusChecker.cpp b/logic/status/StatusChecker.cpp index 54cf077a..7c856d3f 100644 --- a/logic/status/StatusChecker.cpp +++ b/logic/status/StatusChecker.cpp @@ -47,7 +47,6 @@ void StatusChecker::reloadStatus() void StatusChecker::statusDownloadFinished() { - // Parse the XML file and process the RSS feed entries. QLOG_DEBUG() << "Finished loading status JSON."; QByteArray data; -- cgit v1.2.3 From fca4441229808891f460d5fbc4affd51e8896aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 9 Jan 2014 01:22:34 +0100 Subject: Replace old launcher part with a shiny new one. No more garbage on the command line. --- logic/BaseInstance.cpp | 7 ++++ logic/BaseInstance.h | 2 ++ logic/LegacyInstance.cpp | 57 +++++++----------------------- logic/MinecraftProcess.cpp | 51 ++++++++++++++++++++------- logic/MinecraftProcess.h | 15 ++++++-- logic/OneSixInstance.cpp | 88 +++++++++++++++++++++------------------------- 6 files changed, 113 insertions(+), 107 deletions(-) (limited to 'logic') diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index ac66a8d5..4fc6b9dc 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -26,6 +26,7 @@ #include "overridesetting.h" #include "pathutils.h" +#include #include "lists/MinecraftVersionList.h" #include "logic/icons/IconList.h" @@ -248,8 +249,14 @@ void BaseInstance::setName(QString val) d->m_settings->set("name", val); emit propertiesChanged(this); } + QString BaseInstance::name() const { I_D(BaseInstance); return d->m_settings->get("name").toString(); } + +QStringList BaseInstance::extraArguments() const +{ + return Util::Commandline::splitArgs(settings().get("JvmArgs").toString()); +} diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index 01d6dc7d..c059d058 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -81,6 +81,8 @@ public: void setGroupInitial(QString val); void setGroupPost(QString val); + QStringList extraArguments() const; + virtual QString intendedVersionId() const = 0; virtual bool setIntendedVersionId(QString version) = 0; diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 5ab19fc9..4b650e37 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -47,7 +47,7 @@ std::shared_ptr LegacyInstance::doUpdate(bool only_prepare) // make sure the jar mods list is initialized by asking for it. auto list = jarModList(); // create an update task - return std::shared_ptr (new LegacyUpdate(this, only_prepare , this)); + return std::shared_ptr(new LegacyUpdate(this, only_prepare, this)); } MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account) @@ -58,58 +58,27 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account) auto pixmap = icon.pixmap(128, 128); pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG"); - // extract the legacy launcher - QString launcherJar = PathCombine(MMC->bin(), "jars", "MultiMCLauncher.jar"); - - // set the process arguments + // create the launch script + QString launchScript; { - QStringList args; - // window size - QString windowSize; + QString windowParams; if (settings().get("LaunchMaximized").toBool()) - windowSize = "max"; + windowParams = "max"; else - windowSize = QString("%1x%2").arg(settings().get("MinecraftWinWidth").toInt()).arg( + windowParams = QString("%1x%2").arg(settings().get("MinecraftWinWidth").toInt()).arg( settings().get("MinecraftWinHeight").toInt()); - // window title - QString windowTitle; - windowTitle.append("MultiMC: ").append(name()); - - // Java arguments - args.append(Util::Commandline::splitArgs(settings().get("JvmArgs").toString())); - -#ifdef OSX - // OSX dock icon and name - args << "-Xdock:icon=icon.png"; - args << QString("-Xdock:name=\"%1\"").arg(windowTitle); -#endif - QString lwjgl = QDir(MMC->settings()->get("LWJGLDir").toString() + "/" + lwjglVersion()) .absolutePath(); - - // launcher arguments - args << QString("-Xms%1m").arg(settings().get("MinMemAlloc").toInt()); - args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt()); - args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt()); -/** -* HACK: Stupid hack for Intel drivers. -* See: https://mojang.atlassian.net/browse/MCL-767 -*/ -#ifdef Q_OS_WIN32 - args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" - "minecraft.exe.heapdump"); -#endif - - args << "-jar" << launcherJar; - args << account->currentProfile()->name; - args << account->sessionId(); - args << windowTitle; - args << windowSize; - args << lwjgl; - proc->setArguments(args); + launchScript += "userName " + account->currentProfile()->name + "\n"; + launchScript += "sessionId " + account->sessionId() + "\n"; + launchScript += "windowTitle MultiMC: " + name() + "\n"; + launchScript += "windowParams " + windowParams + "\n"; + launchScript += "lwjgl " + lwjgl + "\n"; + launchScript += "launch legacy\n"; } + proc->setLaunchScript(launchScript); // set the process work path proc->setWorkdir(minecraftRoot()); diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 209929b7..153b462c 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "MultiMC.h" #include "MinecraftProcess.h" #include #include #include -//#include #include #include "BaseInstance.h" @@ -59,11 +59,6 @@ MinecraftProcess::MinecraftProcess(BaseInstance *inst) : m_instance(inst) connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); } -void MinecraftProcess::setArguments(QStringList args) -{ - m_args = args; -} - void MinecraftProcess::setWorkdir(QString path) { QDir mcDir(path); @@ -189,13 +184,43 @@ void MinecraftProcess::launch() } m_instance->setLastLaunch(); + auto &settings = m_instance->settings(); + + //////////// java arguments //////////// + QStringList args; + { + // custom args go first. we want to override them if we have our own here. + args.append(m_instance->extraArguments()); + + // OSX dock icon and name + #ifdef OSX + args << "-Xdock:icon=icon.png"; + args << QString("-Xdock:name=\"%1\"").arg(windowTitle); + #endif + + // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767 + #ifdef Q_OS_WIN32 + args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" + "minecraft.exe.heapdump"); + #endif + + args << QString("-Xms%1m").arg(settings.get("MinMemAlloc").toInt()); + args << QString("-Xmx%1m").arg(settings.get("MaxMemAlloc").toInt()); + args << QString("-XX:PermSize=%1m").arg(settings.get("PermGen").toInt()); + if(!m_nativeFolder.isEmpty()) + args << QString("-Djava.library.path=%1").arg(m_nativeFolder); + args << "-jar" << PathCombine(MMC->bin(), "jars", "NewLaunch.jar"); + } - emit log(QString("Minecraft folder is: '%1'").arg(workingDirectory())); QString JavaPath = m_instance->settings().get("JavaPath").toString(); - emit log(QString("Java path: '%1'").arg(JavaPath)); - QString allArgs = m_args.join("' '"); - emit log(QString("Arguments: '%1'").arg(censorPrivateInfo(allArgs))); - start(JavaPath, m_args); + emit log("MultiMC version: " + MMC->version().toString() + "\n\n"); + emit log("Minecraft folder is:\n" + workingDirectory() + "\n\n"); + emit log("Java path is:\n" + JavaPath + "\n\n"); + QString allArgs = args.join(", "); + emit log("Java Arguments:\n[" + censorPrivateInfo(allArgs) + "]\n\n"); + + // instantiate the launcher part + start(JavaPath, args); if (!waitForStarted()) { //: Error message displayed if instace can't start @@ -204,11 +229,13 @@ void MinecraftProcess::launch() emit launch_failed(m_instance); return; } + // send the launch script to the launcher part + QByteArray bytes = launchScript.toUtf8(); + writeData(bytes.constData(), bytes.length()); } MessageLevel::Enum MinecraftProcess::getLevel(const QString &line, MessageLevel::Enum level) { - if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") || line.contains("[FINEST]")) level = MessageLevel::Message; diff --git a/logic/MinecraftProcess.h b/logic/MinecraftProcess.h index bd0151cc..5d1a2b71 100644 --- a/logic/MinecraftProcess.h +++ b/logic/MinecraftProcess.h @@ -18,7 +18,7 @@ #pragma once #include - +#include #include "BaseInstance.h" /** @@ -65,7 +65,15 @@ public: void setWorkdir(QString path); - void setArguments(QStringList args); + void setLaunchScript(QString script) + { + launchScript = script; + } + + void setNativeFolder(QString natives) + { + m_nativeFolder = natives; + } void killMinecraft(); @@ -104,12 +112,13 @@ signals: protected: BaseInstance *m_instance = nullptr; - QStringList m_args; QString m_err_leftover; QString m_out_leftover; QProcess m_prepostlaunchprocess; bool killed = false; MojangAccountPtr m_account; + QString launchScript; + QString m_nativeFolder; protected slots: diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 2392c683..a12cf047 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -13,12 +13,14 @@ * limitations under the License. */ +#include "MultiMC.h" #include "OneSixInstance.h" #include "OneSixInstance_p.h" #include "OneSixUpdate.h" #include "MinecraftProcess.h" #include "OneSixVersion.h" #include "JavaChecker.h" +#include "logic/icons/IconList.h" #include #include @@ -27,6 +29,7 @@ #include "gui/dialogs/OneSixModEditDialog.h" #include "logger/QsLog.h" #include "logic/assets/AssetsUtils.h" +#include OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj, QObject *parent) @@ -40,7 +43,7 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_o std::shared_ptr OneSixInstance::doUpdate(bool only_prepare) { - return std::shared_ptr (new OneSixUpdate(this, only_prepare)); + return std::shared_ptr(new OneSixUpdate(this, only_prepare)); } QString replaceTokensIn(QString text, QMap with) @@ -78,24 +81,25 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr version) QFile indexFile(indexPath); QDir virtualRoot(PathCombine(virtualDir.path(), version->assets)); - if(!indexFile.exists()) + if (!indexFile.exists()) { QLOG_ERROR() << "No assets index file" << indexPath << "; can't reconstruct assets"; return virtualRoot; } - QLOG_DEBUG() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path(); + QLOG_DEBUG() << "reconstructAssets" << assetsDir.path() << indexDir.path() + << objectDir.path() << virtualDir.path() << virtualRoot.path(); AssetsIndex index; bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index); - if(loadAssetsIndex) + if (loadAssetsIndex) { - if(index.isVirtual) + if (index.isVirtual) { QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path(); - for(QString map : index.objects.keys()) + for (QString map : index.objects.keys()) { AssetObject asset_object = index.objects.value(map); QString target_path = PathCombine(virtualRoot.path(), map); @@ -103,17 +107,20 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr version) QString tlk = asset_object.hash.left(2); - QString original_path = PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash); + QString original_path = + PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash); QFile original(original_path); - if(!target.exists()) + if (!target.exists()) { QFileInfo info(target_path); QDir target_dir = info.dir(); - //QLOG_DEBUG() << target_dir; - if(!target_dir.exists()) QDir("").mkpath(target_dir.path()); + // QLOG_DEBUG() << target_dir; + if (!target_dir.exists()) + QDir("").mkpath(target_dir.path()); bool couldCopy = original.copy(target_path); - QLOG_DEBUG() << " Copying" << original_path << "to" << target_path << QString::number(couldCopy);// << original.errorString(); + QLOG_DEBUG() << " Copying" << original_path << "to" << target_path + << QString::number(couldCopy); // << original.errorString(); } } @@ -155,7 +162,7 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account) auto user = account->user(); QJsonObject userAttrs; - for(auto key: user.properties.keys()) + for (auto key : user.properties.keys()) { auto array = QJsonArray::fromStringList(user.properties.values(key)); userAttrs.insert(key, array); @@ -180,71 +187,56 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account) { I_D(OneSixInstance); - QString natives_dir_raw = PathCombine(instanceRoot(), "natives/"); + QIcon icon = MMC->icons()->getIcon(iconKey()); + auto pixmap = icon.pixmap(128, 128); + pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG"); auto version = d->version; if (!version) return nullptr; - - QStringList args; - args.append(Util::Commandline::splitArgs(settings().get("JvmArgs").toString())); - args << QString("-Xms%1m").arg(settings().get("MinMemAlloc").toInt()); - args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt()); - args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt()); - -/** - * HACK: Stupid hack for Intel drivers. - * See: https://mojang.atlassian.net/browse/MCL-767 - */ -#ifdef Q_OS_WIN32 - args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_" - "minecraft.exe.heapdump"); -#endif - - QDir natives_dir(natives_dir_raw); - args << QString("-Djava.library.path=%1").arg(natives_dir.absolutePath()); - QString classPath; + QString launchScript; { auto libs = version->getActiveNormalLibs(); for (auto lib : libs) { QFileInfo fi(QString("libraries/") + lib->storagePath()); - classPath.append(fi.absoluteFilePath()); -#ifdef Q_OS_WIN32 - classPath.append(';'); -#else - classPath.append(':'); -#endif + launchScript += "cp " + fi.absoluteFilePath() + "\n"; } QString targetstr = "versions/" + version->id + "/" + version->id + ".jar"; QFileInfo fi(targetstr); - classPath.append(fi.absoluteFilePath()); + launchScript += "cp " + fi.absoluteFilePath() + "\n"; } - if (classPath.size()) + launchScript += "mainClass " + version->mainClass + "\n"; + + for (auto param : processMinecraftArgs(account)) { - args << "-cp"; - args << classPath; + launchScript += "param " + param + "\n"; } - args << version->mainClass; - args.append(processMinecraftArgs(account)); // Set the width and height for 1.6 instances bool maximize = settings().get("LaunchMaximized").toBool(); if (maximize) { // this is probably a BAD idea - // args << QString("--fullscreen"); + // launchScript += "param --fullscreen\n"; } else { - args << QString("--width") << settings().get("MinecraftWinWidth").toString(); - args << QString("--height") << settings().get("MinecraftWinHeight").toString(); + launchScript += + "param --width\nparam " + settings().get("MinecraftWinWidth").toString() + "\n"; + launchScript += + "param --height\nparam " + settings().get("MinecraftWinHeight").toString() + "\n"; } + QDir natives_dir(PathCombine(instanceRoot(), "natives/")); + launchScript += "windowTitle MultiMC: " + name() + "\n"; + launchScript += "natives " + natives_dir.absolutePath() + "\n"; + launchScript += "launch onesix\n"; // create the process and set its parameters MinecraftProcess *proc = new MinecraftProcess(this); - proc->setArguments(args); proc->setWorkdir(minecraftRoot()); + proc->setLaunchScript(launchScript); + // proc->setNativeFolder(natives_dir.absolutePath()); return proc; } -- cgit v1.2.3 From afd1778fd766011a968074d68241b42b1438fb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 12 Jan 2014 23:38:12 +0100 Subject: Fix window title problem on OSX. --- logic/BaseInstance.cpp | 5 +++++ logic/BaseInstance.h | 3 +++ logic/LegacyInstance.cpp | 2 +- logic/MinecraftProcess.cpp | 2 +- logic/OneSixInstance.cpp | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) (limited to 'logic') diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index 4fc6b9dc..afe3dd03 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -256,6 +256,11 @@ QString BaseInstance::name() const return d->m_settings->get("name").toString(); } +QString BaseInstance::windowTitle() const +{ + return "MultiMC: " + name(); +} + QStringList BaseInstance::extraArguments() const { return Util::Commandline::splitArgs(settings().get("JvmArgs").toString()); diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index c059d058..353ea58a 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -71,6 +71,9 @@ public: QString name() const; void setName(QString val); + /// Value used for instance window titles + QString windowTitle() const; + QString iconKey() const; void setIconKey(QString val); diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp index 4b650e37..2828bcbf 100644 --- a/logic/LegacyInstance.cpp +++ b/logic/LegacyInstance.cpp @@ -73,7 +73,7 @@ MinecraftProcess *LegacyInstance::prepareForLaunch(MojangAccountPtr account) .absolutePath(); launchScript += "userName " + account->currentProfile()->name + "\n"; launchScript += "sessionId " + account->sessionId() + "\n"; - launchScript += "windowTitle MultiMC: " + name() + "\n"; + launchScript += "windowTitle " + windowTitle() + "\n"; launchScript += "windowParams " + windowParams + "\n"; launchScript += "lwjgl " + lwjgl + "\n"; launchScript += "launch legacy\n"; diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 153b462c..09d60771 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -195,7 +195,7 @@ void MinecraftProcess::launch() // OSX dock icon and name #ifdef OSX args << "-Xdock:icon=icon.png"; - args << QString("-Xdock:name=\"%1\"").arg(windowTitle); + args << QString("-Xdock:name=\"%1\"").arg(m_instance->windowTitle()); #endif // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767 diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index a12cf047..16699a1d 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -228,7 +228,7 @@ MinecraftProcess *OneSixInstance::prepareForLaunch(MojangAccountPtr account) "param --height\nparam " + settings().get("MinecraftWinHeight").toString() + "\n"; } QDir natives_dir(PathCombine(instanceRoot(), "natives/")); - launchScript += "windowTitle MultiMC: " + name() + "\n"; + launchScript += "windowTitle " + windowTitle() + "\n"; launchScript += "natives " + natives_dir.absolutePath() + "\n"; launchScript += "launch onesix\n"; -- cgit v1.2.3 From 4744ea07a892bc7066fbb21d394a2ce5efb0bdd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 13 Jan 2014 02:19:20 +0100 Subject: Small fix for stale files getting stuck in the cache --- logic/net/CacheDownload.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'logic') diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 8a8d00f0..0022c361 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -58,11 +58,17 @@ void CacheDownload::start() } QLOG_INFO() << "Downloading " << m_url.toString(); QNetworkRequest request(m_url); - if (m_entry->remote_changed_timestamp.size()) - request.setRawHeader(QString("If-Modified-Since").toLatin1(), - m_entry->remote_changed_timestamp.toLatin1()); - if (m_entry->etag.size()) - request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1()); + + // check file consistency first. + QFile current(m_target_path); + if(current.exists() && current.size() != 0) + { + if (m_entry->remote_changed_timestamp.size()) + request.setRawHeader(QString("If-Modified-Since").toLatin1(), + m_entry->remote_changed_timestamp.toLatin1()); + if (m_entry->etag.size()) + request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1()); + } request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); -- cgit v1.2.3 From 555cbe00ced6097202f148f200811acc6b1eeb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 14 Jan 2014 01:13:35 +0100 Subject: Do not use the java checker during instance update --- logic/OneSixUpdate.cpp | 148 ++++++++++++++++++++++--------------------------- logic/OneSixUpdate.h | 8 --- 2 files changed, 65 insertions(+), 91 deletions(-) (limited to 'logic') diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 4d93477a..5309a7e0 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -54,17 +54,7 @@ void OneSixUpdate::executeTask() if (m_only_prepare) { - /* - * FIXME: in offline mode, do not proceed! - */ - setStatus(tr("Testing the Java installation...")); - QString java_path = m_inst->settings().get("JavaPath").toString(); - - checker.reset(new JavaChecker()); - connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, - SLOT(checkFinishedOffline(JavaCheckResult))); - checker->path = java_path; - checker->performCheck(); + prepareForLaunch(); return; } @@ -83,46 +73,8 @@ void OneSixUpdate::executeTask() } else { - checkJavaOnline(); - } -} - -void OneSixUpdate::checkJavaOnline() -{ - setStatus(tr("Testing the Java installation...")); - QString java_path = m_inst->settings().get("JavaPath").toString(); - - checker.reset(new JavaChecker()); - connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, - SLOT(checkFinishedOnline(JavaCheckResult))); - checker->path = java_path; - checker->performCheck(); -} - -void OneSixUpdate::checkFinishedOnline(JavaCheckResult result) -{ - if (result.valid) - { - java_is_64bit = result.is_64bit; jarlibStart(); } - else - { - emitFailed("The java binary doesn't work. Check the settings and correct the problem"); - } -} - -void OneSixUpdate::checkFinishedOffline(JavaCheckResult result) -{ - if (result.valid) - { - java_is_64bit = result.is_64bit; - prepareForLaunch(); - } - else - { - emitFailed("The java binary doesn't work. Check the settings and correct the problem"); - } } void OneSixUpdate::versionFileStart() @@ -130,7 +82,8 @@ void OneSixUpdate::versionFileStart() QLOG_INFO() << m_inst->name() << ": getting version file."; setStatus(tr("Getting the version files from Mojang...")); - QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; + QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + + targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; auto job = new NetJob("Version index"); job->addNetAction(ByteArrayDownload::make(QUrl(urlstr))); specificVersionDownloadJob.reset(job); @@ -186,7 +139,7 @@ void OneSixUpdate::versionFileFinished() } inst->reloadFullVersion(); - checkJavaOnline(); + jarlibStart(); } void OneSixUpdate::versionFileFailed() @@ -230,7 +183,7 @@ void OneSixUpdate::assetIndexFinished() { emitFailed("Failed to read the assets index!"); } - + QList dls; for (auto object : index.objects.values()) { @@ -245,17 +198,17 @@ void OneSixUpdate::assetIndexFinished() dls.append(objectDL); } } - if(dls.size()) + if (dls.size()) { setStatus(tr("Getting the assets files from Mojang...")); auto job = new NetJob("Assets for " + inst->name()); - for(auto dl: dls) + for (auto dl : dls) job->addNetAction(dl); jarlibDownloadJob.reset(job); connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished())); connect(jarlibDownloadJob.get(), SIGNAL(failed()), SLOT(assetsFailed())); connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); + SIGNAL(progress(qint64, qint64))); jarlibDownloadJob->start(); return; } @@ -277,8 +230,6 @@ void OneSixUpdate::assetsFailed() emitFailed("Failed to download assets!"); } - - void OneSixUpdate::jarlibStart() { setStatus(tr("Getting the library files from Mojang...")); @@ -318,24 +269,37 @@ void OneSixUpdate::jarlibStart() { if (lib->hint() == "local") continue; - QString subst = java_is_64bit ? "64" : "32"; - QString storage = lib->storagePath(); - QString dl = lib->downloadUrl(); - storage.replace("${arch}", subst); - dl.replace("${arch}", subst); + QString raw_storage = lib->storagePath(); + QString raw_dl = lib->downloadUrl(); - auto entry = metacache->resolveEntry("libraries", storage); - if (entry->stale) + auto f = [&](QString storage, QString dl) { - if (lib->hint() == "forge-pack-xz") + auto entry = metacache->resolveEntry("libraries", storage); + if (entry->stale) { - ForgeLibs.append(ForgeXzDownload::make(storage, entry)); - } - else - { - jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry)); + if (lib->hint() == "forge-pack-xz") + { + ForgeLibs.append(ForgeXzDownload::make(storage, entry)); + } + else + { + jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry)); + } } + }; + if (raw_storage.contains("${arch}")) + { + QString cooked_storage = raw_storage; + QString cooked_dl = raw_dl; + f(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32")); + cooked_storage = raw_storage; + cooked_dl = raw_dl; + f(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64")); + } + else + { + f(raw_storage, raw_dl); } } // TODO: think about how to propagate this from the original json file... or IF AT ALL @@ -388,7 +352,9 @@ void OneSixUpdate::prepareForLaunch() auto libs_to_extract = version->getActiveNativeLibs(); // Acquire bag - bool success = ensureFolderPathExists(natives_dir_raw); + bool success = true; + success &= ensureFolderPathExists(natives_dir_raw + "/32"); + success &= ensureFolderPathExists(natives_dir_raw + "/64"); if (!success) { emitFailed("Could not create the native library folder:\n" + natives_dir_raw + @@ -398,22 +364,38 @@ void OneSixUpdate::prepareForLaunch() } // Put swag in the bag - QString subst = java_is_64bit ? "64" : "32"; for (auto lib : libs_to_extract) { + auto f = [&](QString storage, QString arch = "") + { + QString path = "libraries/" + storage; + QLOG_INFO() << "Will extract " << path.toLocal8Bit(); + if (JlCompress::extractWithExceptions(path, natives_dir_raw + "/" + arch, + lib->extract_excludes).isEmpty()) + { + emitFailed( + "Could not extract the native library:\n" + path + + "\nMake sure MultiMC has appropriate permissions and there is enough space " + "on the storage device."); + return false; + } + }; QString storage = lib->storagePath(); - storage.replace("${arch}", subst); - - QString path = "libraries/" + storage; - QLOG_INFO() << "Will extract " << path.toLocal8Bit(); - if (JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes) - .isEmpty()) + if (storage.contains("${arch}")) { - emitFailed( - "Could not extract the native library:\n" + path + - "\nMake sure MultiMC has appropriate permissions and there is enough space " - "on the storage device."); - return; + QString cooked_storage = storage; + cooked_storage.replace("${arch}", "32"); + if (!f(cooked_storage, "32")) + return; + cooked_storage = storage; + cooked_storage.replace("${arch}", "64"); + if (!f(cooked_storage, "64")) + return; + } + else + { + if (!f(storage)) + return; } } diff --git a/logic/OneSixUpdate.h b/logic/OneSixUpdate.h index 00b769c7..bc717a94 100644 --- a/logic/OneSixUpdate.h +++ b/logic/OneSixUpdate.h @@ -21,7 +21,6 @@ #include "logic/net/NetJob.h" #include "logic/tasks/Task.h" -#include "logic/JavaChecker.h" class MinecraftVersion; class BaseInstance; @@ -50,10 +49,6 @@ slots: void assetsFinished(); void assetsFailed(); - void checkJavaOnline(); - void checkFinishedOnline(JavaCheckResult result); - void checkFinishedOffline(JavaCheckResult result); - // extract the appropriate libraries void prepareForLaunch(); @@ -65,7 +60,4 @@ private: std::shared_ptr targetVersion; BaseInstance *m_inst = nullptr; bool m_only_prepare = false; - std::shared_ptr checker; - - bool java_is_64bit = false; }; -- cgit v1.2.3 From d85e820a070ea81ee9b76553c3e35948ef785426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 15 Jan 2014 22:49:37 +0100 Subject: Fix FTB. Add support of private packs. Fix instance ID problems related to FTB instances. --- logic/BaseInstance.h | 2 +- logic/LegacyFTBInstance.cpp | 5 +++ logic/LegacyFTBInstance.h | 1 + logic/OneSixFTBInstance.cpp | 5 +++ logic/OneSixFTBInstance.h | 2 ++ logic/lists/InstanceList.cpp | 73 ++++++++++++++++++++++++-------------------- 6 files changed, 54 insertions(+), 34 deletions(-) (limited to 'logic') diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index 353ea58a..a861e9b2 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -57,7 +57,7 @@ public: /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to /// be unique. - QString id() const; + virtual QString id() const; /// get the type of this instance QString instanceType() const; diff --git a/logic/LegacyFTBInstance.cpp b/logic/LegacyFTBInstance.cpp index 84d5a900..6c6bd10b 100644 --- a/logic/LegacyFTBInstance.cpp +++ b/logic/LegacyFTBInstance.cpp @@ -14,3 +14,8 @@ bool LegacyFTBInstance::menuActionEnabled(QString action_name) const { return false; } + +QString LegacyFTBInstance::id() const +{ + return "FTB/" + BaseInstance::id(); +} diff --git a/logic/LegacyFTBInstance.h b/logic/LegacyFTBInstance.h index 2ae72797..70f60535 100644 --- a/logic/LegacyFTBInstance.h +++ b/logic/LegacyFTBInstance.h @@ -10,4 +10,5 @@ public: QObject *parent = 0); virtual QString getStatusbarDescription(); virtual bool menuActionEnabled(QString action_name) const; + virtual QString id() const; }; diff --git a/logic/OneSixFTBInstance.cpp b/logic/OneSixFTBInstance.cpp index 4bb5cf42..e50a5b53 100644 --- a/logic/OneSixFTBInstance.cpp +++ b/logic/OneSixFTBInstance.cpp @@ -92,6 +92,11 @@ OneSixFTBInstance::OneSixFTBInstance(const QString &rootDir, SettingsObject *set } } +QString OneSixFTBInstance::id() const +{ + return "FTB/" + BaseInstance::id(); +} + QString OneSixFTBInstance::getStatusbarDescription() { return "OneSix FTB: " + intendedVersionId(); diff --git a/logic/OneSixFTBInstance.h b/logic/OneSixFTBInstance.h index 7600090c..dc028819 100644 --- a/logic/OneSixFTBInstance.h +++ b/logic/OneSixFTBInstance.h @@ -15,6 +15,8 @@ public: virtual std::shared_ptr doUpdate(bool only_prepare) override; + virtual QString id() const; + private: std::shared_ptr m_forge; }; diff --git a/logic/lists/InstanceList.cpp b/logic/lists/InstanceList.cpp index bfd183d9..0d4eab95 100644 --- a/logic/lists/InstanceList.cpp +++ b/logic/lists/InstanceList.cpp @@ -308,45 +308,52 @@ void InstanceList::loadForgeInstances(QMap groupMap) return; } dir.cd("ModPacks"); - auto fpath = dir.absoluteFilePath("modpacks.xml"); - QFile f(fpath); - QLOG_INFO() << "Discovering FTB instances -- " << fpath; - if (!f.open(QFile::ReadOnly)) - return; - - // read the FTB packs XML. - QXmlStreamReader reader(&f); - while (!reader.atEnd()) + auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name); + for(auto filename: allFiles) { - switch (reader.readNext()) - { - case QXmlStreamReader::StartElement: + if(!filename.endsWith(".xml")) + continue; + auto fpath = dir.absoluteFilePath(filename); + QFile f(fpath); + QLOG_INFO() << "Discovering FTB instances -- " << fpath; + if (!f.open(QFile::ReadOnly)) + continue; + + // read the FTB packs XML. + QXmlStreamReader reader(&f); + while (!reader.atEnd()) { - if (reader.name() == "modpack") + switch (reader.readNext()) { - QXmlStreamAttributes attrs = reader.attributes(); - FTBRecord record; - record.dir = attrs.value("dir").toString(); - QDir test(dataDir.absoluteFilePath(record.dir)); - if(!test.exists()) - continue; - record.name = attrs.value("name").toString(); - record.logo = attrs.value("logo").toString(); - record.mcVersion = attrs.value("mcVersion").toString(); - record.description = attrs.value("description").toString(); - records.append(record); + case QXmlStreamReader::StartElement: + { + if (reader.name() == "modpack") + { + QXmlStreamAttributes attrs = reader.attributes(); + FTBRecord record; + record.dir = attrs.value("dir").toString(); + QDir test(dataDir.absoluteFilePath(record.dir)); + if(!test.exists()) + continue; + record.name = attrs.value("name").toString(); + record.logo = attrs.value("logo").toString(); + record.mcVersion = attrs.value("mcVersion").toString(); + record.description = attrs.value("description").toString(); + records.append(record); + } + break; + } + case QXmlStreamReader::EndElement: + break; + case QXmlStreamReader::Characters: + break; + default: + break; } - break; - } - case QXmlStreamReader::EndElement: - break; - case QXmlStreamReader::Characters: - break; - default: - break; } + f.close(); } - f.close(); + if(!records.size()) { QLOG_INFO() << "No FTB instances to load."; -- cgit v1.2.3 From 7b96d74d3b197c23324c5a364809a91ea6800e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 16 Jan 2014 23:06:07 +0100 Subject: Sort forge versions right. Do not spam the multimc log with mc server status stuff. --- logic/BaseVersion.h | 9 +++++++++ logic/lists/ForgeVersionList.cpp | 8 ++------ logic/lists/ForgeVersionList.h | 21 +++++++++++++++++---- logic/status/StatusChecker.cpp | 6 +++--- 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'logic') diff --git a/logic/BaseVersion.h b/logic/BaseVersion.h index 1864c94c..43f5942a 100644 --- a/logic/BaseVersion.h +++ b/logic/BaseVersion.h @@ -39,6 +39,15 @@ struct BaseVersion * the kind of version this is (Stable, Beta, Snapshot, whatever) */ virtual QString typeString() const = 0; + + virtual bool operator<(BaseVersion &a) + { + return name() < a.name(); + }; + virtual bool operator>(BaseVersion &a) + { + return name() > a.name(); + }; }; typedef std::shared_ptr BaseVersionPtr; diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp index 56eca744..38e033fa 100644 --- a/logic/lists/ForgeVersionList.cpp +++ b/logic/lists/ForgeVersionList.cpp @@ -404,12 +404,8 @@ void ForgeListLoadTask::listDownloaded() { return; } - - qSort(list.begin(), list.end(), [](const BaseVersionPtr & p1, const BaseVersionPtr & p2) - { - // TODO better comparison (takes major/minor/build number into account) - return p1->name() > p2->name(); - }); + std::sort(list.begin(), list.end(), [](const BaseVersionPtr & l, const BaseVersionPtr & r) + { return (*l > *r); }); m_list->updateListData(list); diff --git a/logic/lists/ForgeVersionList.h b/logic/lists/ForgeVersionList.h index 924084ae..b19d3f56 100644 --- a/logic/lists/ForgeVersionList.h +++ b/logic/lists/ForgeVersionList.h @@ -29,25 +29,38 @@ typedef std::shared_ptr ForgeVersionPtr; struct ForgeVersion : public BaseVersion { - virtual QString descriptor() + virtual QString descriptor() override { return filename; } ; - virtual QString name() + virtual QString name() override { return "Forge " + jobbuildver; } ; - virtual QString typeString() const + virtual QString typeString() const override { if (installer_url.isEmpty()) return "Universal"; else return "Installer"; } - ; + virtual bool operator<(BaseVersion &a) override + { + ForgeVersion *pa = dynamic_cast(&a); + if(!pa) + return true; + return m_buildnr < pa->m_buildnr; + } + virtual bool operator>(BaseVersion &a) override + { + ForgeVersion *pa = dynamic_cast(&a); + if(!pa) + return false; + return m_buildnr > pa->m_buildnr; + } int m_buildnr = 0; QString universal_url; QString changelog_url; diff --git a/logic/status/StatusChecker.cpp b/logic/status/StatusChecker.cpp index 7c856d3f..66f800ae 100644 --- a/logic/status/StatusChecker.cpp +++ b/logic/status/StatusChecker.cpp @@ -31,11 +31,11 @@ void StatusChecker::reloadStatus() { if (isLoadingStatus()) { - QLOG_INFO() << "Ignored request to reload status. Currently reloading already."; + // QLOG_INFO() << "Ignored request to reload status. Currently reloading already."; return; } - QLOG_INFO() << "Reloading status."; + // QLOG_INFO() << "Reloading status."; NetJob* job = new NetJob("Status JSON"); job->addNetAction(ByteArrayDownload::make(URLConstants::MOJANG_STATUS_URL)); @@ -85,7 +85,7 @@ void StatusChecker::statusDownloadFinished() if(value.type() == QVariant::Type::String) { m_statusEntries.insert(key, value.toString()); - QLOG_DEBUG() << "Status JSON object: " << key << m_statusEntries[key]; + //QLOG_DEBUG() << "Status JSON object: " << key << m_statusEntries[key]; } else { -- cgit v1.2.3 From 188d0d58865f5e134b5803bda2cd631a61cf2915 Mon Sep 17 00:00:00 2001 From: Orochimarufan Date: Fri, 17 Jan 2014 22:55:10 +0100 Subject: Improve Console window output. -> Log Pre- and Post-Launch command happenings -> Enable the java part to specify the level TODO: fix logging with mc 1.7's log4j logging infrastructure Signed-off-by: Orochimarufan --- logic/BaseInstance.cpp | 1 + logic/MinecraftProcess.cpp | 203 ++++++++++++++++++++++++++++++++++++--------- logic/MinecraftProcess.h | 17 +++- 3 files changed, 177 insertions(+), 44 deletions(-) (limited to 'logic') diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index afe3dd03..222004a3 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -82,6 +82,7 @@ BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir, settings().registerSetting("OverrideConsole", false); settings().registerOverride(globalSettings->getSetting("ShowConsole")); settings().registerOverride(globalSettings->getSetting("AutoCloseConsole")); + settings().registerOverride(globalSettings->getSetting("LogPrePostOutput")); } void BaseInstance::iconUpdated(QString key) diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 18d63674..84610021 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "BaseInstance.h" @@ -42,6 +43,7 @@ MinecraftProcess::MinecraftProcess(BaseInstance *inst) : m_instance(inst) #ifdef LINUX // Strip IBus + // IBus is a Linux IME framework. For some reason, it breaks MC? if (env.value("XMODIFIERS").contains(IBUS)) env.insert("XMODIFIERS", env.value("XMODIFIERS").replace(IBUS, "")); #endif @@ -57,6 +59,15 @@ MinecraftProcess::MinecraftProcess(BaseInstance *inst) : m_instance(inst) // std channels connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr())); connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); + + // Log prepost launch command output (can be disabled.) + if (m_instance->settings().get("LogPrePostOutput").toBool()) + { + connect(&m_prepostlaunchprocess, &QProcess::readyReadStandardError, + this, &MinecraftProcess::on_prepost_stdErr); + connect(&m_prepostlaunchprocess, &QProcess::readyReadStandardOutput, + this, &MinecraftProcess::on_prepost_stdOut); + } } void MinecraftProcess::setWorkdir(QString path) @@ -97,43 +108,133 @@ QString MinecraftProcess::censorPrivateInfo(QString in) } // console window +MessageLevel::Enum MinecraftProcess::guessLevel(const QString &line, MessageLevel::Enum level) +{ + if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || + line.contains("[FINER]") || line.contains("[FINEST]")) + level = MessageLevel::Message; + if (line.contains("[SEVERE]") || line.contains("[STDERR]")) + level = MessageLevel::Error; + if (line.contains("[WARNING]")) + level = MessageLevel::Warning; + if (line.contains("Exception in thread") || line.contains(" at ")) + level = MessageLevel::Fatal; + if (line.contains("[DEBUG]")) + level = MessageLevel::Debug; + return level; +} + +MessageLevel::Enum MinecraftProcess::getLevel(const QString &levelName) +{ + if (levelName == "MultiMC") + return MessageLevel::MultiMC; + else if (levelName == "Debug") + return MessageLevel::Debug; + else if (levelName == "Info") + return MessageLevel::Info; + else if (levelName == "Message") + return MessageLevel::Message; + else if (levelName == "Warning") + return MessageLevel::Warning; + else if (levelName == "Error") + return MessageLevel::Error; + else if (levelName == "Fatal") + return MessageLevel::Fatal; + // Skip PrePost, it's not exposed to !![]! + else + return MessageLevel::Message; +} + +void MinecraftProcess::logOutput(const QStringList &lines, + MessageLevel::Enum defaultLevel, + bool guessLevel, bool censor) +{ + for (int i = 0; i < lines.size(); ++i) + logOutput(lines[i], defaultLevel, guessLevel, censor); +} + +void MinecraftProcess::logOutput(QString line, + MessageLevel::Enum defaultLevel, + bool guessLevel, bool censor) +{ + MessageLevel::Enum level = defaultLevel; + + // Level prefix + int endmark = line.indexOf("]!"); + if (line.startsWith("!![") && endmark != -1) + { + level = getLevel(line.left(endmark).mid(3)); + line = line.mid(endmark + 2); + } + // Guess level + else if (guessLevel) + level = this->guessLevel(line, defaultLevel); + + if (censor) + line = censorPrivateInfo(line); + + emit log(line, level); +} + void MinecraftProcess::on_stdErr() { QByteArray data = readAllStandardError(); QString str = m_err_leftover + QString::fromLocal8Bit(data); - m_err_leftover.clear(); + QStringList lines = str.split("\n"); - bool complete = str.endsWith("\n"); + m_err_leftover = lines.takeLast(); - for (int i = 0; i < lines.size() - 1; i++) - { - QString &line = lines[i]; - emit log(censorPrivateInfo(line), getLevel(line, MessageLevel::Error)); - } - if (!complete) - m_err_leftover = lines.last(); + logOutput(lines, MessageLevel::Error); } void MinecraftProcess::on_stdOut() { QByteArray data = readAllStandardOutput(); QString str = m_out_leftover + QString::fromLocal8Bit(data); - m_out_leftover.clear(); + QStringList lines = str.split("\n"); - bool complete = str.endsWith("\n"); + m_out_leftover = lines.takeLast(); - for (int i = 0; i < lines.size() - 1; i++) - { - QString &line = lines[i]; - emit log(censorPrivateInfo(line), getLevel(line, MessageLevel::Message)); - } - if (!complete) - m_out_leftover = lines.last(); + logOutput(lines); +} + +void MinecraftProcess::on_prepost_stdErr() +{ + QByteArray data = m_prepostlaunchprocess.readAllStandardError(); + QString str = m_err_leftover + QString::fromLocal8Bit(data); + + QStringList lines = str.split("\n"); + m_err_leftover = lines.takeLast(); + + logOutput(lines, MessageLevel::PrePost, false, false); +} + +void MinecraftProcess::on_prepost_stdOut() +{ + QByteArray data = m_prepostlaunchprocess.readAllStandardOutput(); + QString str = m_out_leftover + QString::fromLocal8Bit(data); + + QStringList lines = str.split("\n"); + m_out_leftover = lines.takeLast(); + + logOutput(lines, MessageLevel::PrePost, false, false); } // exit handler void MinecraftProcess::finish(int code, ExitStatus status) { + // Flush console window + if (!m_err_leftover.isEmpty()) + { + logOutput(m_err_leftover, MessageLevel::Error); + m_err_leftover.clear(); + } + if (!m_out_leftover.isEmpty()) + { + logOutput(m_out_leftover); + m_out_leftover.clear(); + } + if (!killed) { if (status == NormalExit) @@ -156,15 +257,32 @@ void MinecraftProcess::finish(int code, ExitStatus status) m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code)); // run post-exit - if (!m_instance->settings().get("PostExitCommand").toString().isEmpty()) + QString postlaunch_cmd = m_instance->settings().get("PostExitCommand").toString(); + if (!postlaunch_cmd.isEmpty()) { - m_prepostlaunchprocess.start(m_instance->settings().get("PostExitCommand").toString()); + emit log(tr("Running Post-Launch command: %1").arg(postlaunch_cmd)); + m_prepostlaunchprocess.start(postlaunch_cmd); m_prepostlaunchprocess.waitForFinished(); + // Flush console window + if (!m_err_leftover.isEmpty()) + { + logOutput(m_err_leftover, MessageLevel::PrePost); + m_err_leftover.clear(); + } + if (!m_out_leftover.isEmpty()) + { + logOutput(m_out_leftover, MessageLevel::PrePost); + m_out_leftover.clear(); + } if (m_prepostlaunchprocess.exitStatus() != NormalExit) { + emit log(tr("Post-Launch command failed with code %1.\n\n").arg(m_prepostlaunchprocess.exitCode()), + MessageLevel::Error); emit postlaunch_failed(m_instance, m_prepostlaunchprocess.exitCode(), m_prepostlaunchprocess.exitStatus()); } + else + emit log(tr("Post-Launch command ran successfully.\n\n")); } m_instance->cleanupAfterRun(); emit ended(m_instance, code, status); @@ -178,17 +296,40 @@ void MinecraftProcess::killMinecraft() void MinecraftProcess::launch() { - if (!m_instance->settings().get("PreLaunchCommand").toString().isEmpty()) + emit log("MultiMC version: " + MMC->version().toString() + "\n\n"); + emit log("Minecraft folder is:\n" + workingDirectory() + "\n\n"); + + QString prelaunch_cmd = m_instance->settings().get("PreLaunchCommand").toString(); + if (!prelaunch_cmd.isEmpty()) { - m_prepostlaunchprocess.start(m_instance->settings().get("PreLaunchCommand").toString()); + // Launch + emit log(tr("Running Pre-Launch command: %1").arg(prelaunch_cmd)); + m_prepostlaunchprocess.start(prelaunch_cmd); + // Wait m_prepostlaunchprocess.waitForFinished(); + // Flush console window + if (!m_err_leftover.isEmpty()) + { + logOutput(m_err_leftover, MessageLevel::PrePost); + m_err_leftover.clear(); + } + if (!m_out_leftover.isEmpty()) + { + logOutput(m_out_leftover, MessageLevel::PrePost); + m_out_leftover.clear(); + } + // Process return values if (m_prepostlaunchprocess.exitStatus() != NormalExit) { + emit log(tr("Pre-Launch command failed with code %1.\n\n").arg(m_prepostlaunchprocess.exitCode()), + MessageLevel::Fatal); m_instance->cleanupAfterRun(); emit prelaunch_failed(m_instance, m_prepostlaunchprocess.exitCode(), m_prepostlaunchprocess.exitStatus()); return; } + else + emit log(tr("Pre-Launch command ran successfully.\n\n")); } m_instance->setLastLaunch(); @@ -221,8 +362,6 @@ void MinecraftProcess::launch() } QString JavaPath = m_instance->settings().get("JavaPath").toString(); - emit log("MultiMC version: " + MMC->version().toString() + "\n\n"); - emit log("Minecraft folder is:\n" + workingDirectory() + "\n\n"); emit log("Java path is:\n" + JavaPath + "\n\n"); QString allArgs = args.join(", "); emit log("Java Arguments:\n[" + censorPrivateInfo(allArgs) + "]\n\n"); @@ -241,19 +380,3 @@ void MinecraftProcess::launch() QByteArray bytes = launchScript.toUtf8(); writeData(bytes.constData(), bytes.length()); } - -MessageLevel::Enum MinecraftProcess::getLevel(const QString &line, MessageLevel::Enum level) -{ - if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || - line.contains("[FINER]") || line.contains("[FINEST]")) - level = MessageLevel::Message; - if (line.contains("[SEVERE]") || line.contains("[STDERR]")) - level = MessageLevel::Error; - if (line.contains("[WARNING]")) - level = MessageLevel::Warning; - if (line.contains("Exception in thread") || line.contains(" at ")) - level = MessageLevel::Fatal; - if (line.contains("[DEBUG]")) - level = MessageLevel::Debug; - return level; -} diff --git a/logic/MinecraftProcess.h b/logic/MinecraftProcess.h index 5d1a2b71..70e5df52 100644 --- a/logic/MinecraftProcess.h +++ b/logic/MinecraftProcess.h @@ -31,11 +31,12 @@ enum Enum { MultiMC, /**< MultiMC Messages */ Debug, /**< Debug Messages */ - Info, /**< Info Messages */ + Info, /**< Info Messages */ Message, /**< Standard Messages */ Warning, /**< Warnings */ Error, /**< Errors */ - Fatal /**< Fatal Errors */ + Fatal, /**< Fatal Errors */ + PrePost, /**< Pre/Post Launch command output */ }; } @@ -125,9 +126,17 @@ slots: void finish(int, QProcess::ExitStatus status); void on_stdErr(); void on_stdOut(); + void on_prepost_stdOut(); + void on_prepost_stdErr(); + void logOutput(const QStringList &lines, + MessageLevel::Enum defaultLevel = MessageLevel::Message, + bool guessLevel = true, bool censor = true); + void logOutput(QString line, + MessageLevel::Enum defaultLevel = MessageLevel::Message, + bool guessLevel = true, bool censor = true); private: QString censorPrivateInfo(QString in); - MessageLevel::Enum getLevel(const QString &message, MessageLevel::Enum defaultLevel); - + MessageLevel::Enum guessLevel(const QString &message, MessageLevel::Enum defaultLevel); + MessageLevel::Enum getLevel(const QString &levelName); }; -- cgit v1.2.3 From ecc80bd763111b0e368aa80366bd8382cd814ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 18 Jan 2014 03:32:31 +0100 Subject: Change the native extraction/loading logic. --- logic/OneSixLibrary.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ logic/OneSixLibrary.h | 2 ++ logic/OneSixUpdate.cpp | 55 +++++++++--------------------------------------- 3 files changed, 68 insertions(+), 45 deletions(-) (limited to 'logic') diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp index 4b6ed9dc..1d69b660 100644 --- a/logic/OneSixLibrary.cpp +++ b/logic/OneSixLibrary.cpp @@ -19,6 +19,9 @@ #include "OneSixRule.h" #include "OpSys.h" #include "logic/net/URLConstants.h" +#include +#include +#include "logger/QsLog.h" void OneSixLibrary::finalize() { @@ -133,6 +136,59 @@ QString OneSixLibrary::hint() return m_hint; } +bool OneSixLibrary::extractTo(QString target_dir) +{ + QString storage = storagePath(); + if (storage.contains("${arch}")) + { + QString cooked_storage = storage; + cooked_storage.replace("${arch}", "32"); + QString origin = PathCombine("libraries", cooked_storage); + QString target_dir_cooked = PathCombine(target_dir, "32"); + if(!ensureFolderPathExists(target_dir_cooked)) + { + QLOG_ERROR() << "Couldn't create folder " + target_dir_cooked; + return false; + } + if (JlCompress::extractWithExceptions(origin, target_dir_cooked, extract_excludes) + .isEmpty()) + { + QLOG_ERROR() << "Couldn't extract " + origin; + return false; + } + cooked_storage = storage; + cooked_storage.replace("${arch}", "64"); + origin = PathCombine("libraries", cooked_storage); + target_dir_cooked = PathCombine(target_dir, "32"); + if(!ensureFolderPathExists(target_dir_cooked)) + { + QLOG_ERROR() << "Couldn't create folder " + target_dir_cooked; + return false; + } + if (JlCompress::extractWithExceptions(origin, target_dir_cooked, extract_excludes) + .isEmpty()) + { + QLOG_ERROR() << "Couldn't extract " + origin; + return false; + } + } + else + { + if(!ensureFolderPathExists(target_dir)) + { + QLOG_ERROR() << "Couldn't create folder " + target_dir; + return false; + } + QString path = PathCombine("libraries", storage); + if (JlCompress::extractWithExceptions(path, target_dir, extract_excludes).isEmpty()) + { + QLOG_ERROR() << "Couldn't extract " + path; + return false; + } + } + return true; +} + QJsonObject OneSixLibrary::toJson() { QJsonObject libRoot; diff --git a/logic/OneSixLibrary.h b/logic/OneSixLibrary.h index 3f0bc83d..bc097348 100644 --- a/logic/OneSixLibrary.h +++ b/logic/OneSixLibrary.h @@ -126,4 +126,6 @@ public: /// set a hint about how to treat the library. This is an MMC extension. void setHint(QString hint); QString hint(); + + bool extractTo(QString target_dir); }; diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 5309a7e0..ee355308 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -340,7 +340,6 @@ void OneSixUpdate::prepareForLaunch() // delete any leftovers, if they are present. onesix_inst->cleanupAfterRun(); - // Acquire swag QString natives_dir_raw = PathCombine(onesix_inst->instanceRoot(), "natives/"); auto version = onesix_inst->getFullVersion(); if (!version) @@ -349,56 +348,22 @@ void OneSixUpdate::prepareForLaunch() "it or changing the version."); return; } - auto libs_to_extract = version->getActiveNativeLibs(); - - // Acquire bag - bool success = true; - success &= ensureFolderPathExists(natives_dir_raw + "/32"); - success &= ensureFolderPathExists(natives_dir_raw + "/64"); - if (!success) - { - emitFailed("Could not create the native library folder:\n" + natives_dir_raw + +/* + * emitFailed("Could not create the native library folder:\n" + natives_dir_raw + "\nMake sure MultiMC has appropriate permissions and there is enough space " "on the storage device."); - return; - } - - // Put swag in the bag - for (auto lib : libs_to_extract) +*/ + for (auto lib : version->getActiveNativeLibs()) { - auto f = [&](QString storage, QString arch = "") + if (!lib->extractTo(natives_dir_raw)) { - QString path = "libraries/" + storage; - QLOG_INFO() << "Will extract " << path.toLocal8Bit(); - if (JlCompress::extractWithExceptions(path, natives_dir_raw + "/" + arch, - lib->extract_excludes).isEmpty()) - { - emitFailed( - "Could not extract the native library:\n" + path + - "\nMake sure MultiMC has appropriate permissions and there is enough space " - "on the storage device."); - return false; - } - }; - QString storage = lib->storagePath(); - if (storage.contains("${arch}")) - { - QString cooked_storage = storage; - cooked_storage.replace("${arch}", "32"); - if (!f(cooked_storage, "32")) - return; - cooked_storage = storage; - cooked_storage.replace("${arch}", "64"); - if (!f(cooked_storage, "64")) - return; - } - else - { - if (!f(storage)) - return; + emitFailed("Could not extract the native library:\n" + lib->storagePath() + " to " + + natives_dir_raw + + "\nMake sure MultiMC has appropriate permissions and there is enough " + "space on the storage device."); + return; } } - // Show them your war face! emitSucceeded(); } -- cgit v1.2.3 From 3fabb11f4c59baffb14db00d338d9efe342e277e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 18 Jan 2014 22:11:33 +0100 Subject: Marginally improve OneSix offline mode launch While reconstructing assets, skip files that don't exist. Report missing OneSix native libraries. --- logic/OneSixInstance.cpp | 55 +++++++++++++++++------------------ logic/OneSixLibrary.cpp | 28 ++++++++++++++++++ logic/OneSixLibrary.h | 1 + logic/OneSixUpdate.cpp | 20 +++++++++---- logic/auth/MojangAccount.cpp | 6 +++- logic/lists/ForgeVersionList.cpp | 4 +-- logic/net/CacheDownload.cpp | 21 ++++++++----- logic/net/CacheDownload.h | 9 ++++-- logic/updater/NotificationChecker.cpp | 2 +- 9 files changed, 97 insertions(+), 49 deletions(-) (limited to 'logic') diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index 16699a1d..3cfc1c76 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -93,39 +93,38 @@ QDir OneSixInstance::reconstructAssets(std::shared_ptr version) AssetsIndex index; bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(indexPath, &index); - if (loadAssetsIndex) + if (loadAssetsIndex && index.isVirtual) { - if (index.isVirtual) - { - QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path(); + QLOG_INFO() << "Reconstructing virtual assets folder at" << virtualRoot.path(); - for (QString map : index.objects.keys()) + for (QString map : index.objects.keys()) + { + AssetObject asset_object = index.objects.value(map); + QString target_path = PathCombine(virtualRoot.path(), map); + QFile target(target_path); + + QString tlk = asset_object.hash.left(2); + + QString original_path = + PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash); + QFile original(original_path); + if(!original.exists()) + continue; + if (!target.exists()) { - AssetObject asset_object = index.objects.value(map); - QString target_path = PathCombine(virtualRoot.path(), map); - QFile target(target_path); - - QString tlk = asset_object.hash.left(2); - - QString original_path = - PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash); - QFile original(original_path); - if (!target.exists()) - { - QFileInfo info(target_path); - QDir target_dir = info.dir(); - // QLOG_DEBUG() << target_dir; - if (!target_dir.exists()) - QDir("").mkpath(target_dir.path()); - - bool couldCopy = original.copy(target_path); - QLOG_DEBUG() << " Copying" << original_path << "to" << target_path - << QString::number(couldCopy); // << original.errorString(); - } + QFileInfo info(target_path); + QDir target_dir = info.dir(); + // QLOG_DEBUG() << target_dir; + if (!target_dir.exists()) + QDir("").mkpath(target_dir.path()); + + bool couldCopy = original.copy(target_path); + QLOG_DEBUG() << " Copying" << original_path << "to" << target_path + << QString::number(couldCopy); // << original.errorString(); } - - // TODO: Write last used time to virtualRoot/.lastused } + + // TODO: Write last used time to virtualRoot/.lastused } return virtualRoot; diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp index 1d69b660..cf29a832 100644 --- a/logic/OneSixLibrary.cpp +++ b/logic/OneSixLibrary.cpp @@ -136,6 +136,34 @@ QString OneSixLibrary::hint() return m_hint; } +bool OneSixLibrary::filesExist() +{ + QString storage = storagePath(); + if (storage.contains("${arch}")) + { + QString cooked_storage = storage; + cooked_storage.replace("${arch}", "32"); + if (!QFileInfo::exists(PathCombine("libraries", cooked_storage))) + { + return false; + } + cooked_storage = storage; + cooked_storage.replace("${arch}", "64"); + if (!QFileInfo::exists(PathCombine("libraries", cooked_storage))) + { + return false; + } + } + else + { + if (!QFileInfo::exists(PathCombine("libraries", storage))) + { + return false; + } + } + return true; +} + bool OneSixLibrary::extractTo(QString target_dir) { QString storage = storagePath(); diff --git a/logic/OneSixLibrary.h b/logic/OneSixLibrary.h index bc097348..227cdbef 100644 --- a/logic/OneSixLibrary.h +++ b/logic/OneSixLibrary.h @@ -128,4 +128,5 @@ public: QString hint(); bool extractTo(QString target_dir); + bool filesExist(); }; diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index ee355308..0119ab07 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -348,18 +348,26 @@ void OneSixUpdate::prepareForLaunch() "it or changing the version."); return; } -/* - * emitFailed("Could not create the native library folder:\n" + natives_dir_raw + - "\nMake sure MultiMC has appropriate permissions and there is enough space " - "on the storage device."); -*/ + /* + * emitFailed("Could not create the native library folder:\n" + natives_dir_raw + + "\nMake sure MultiMC has appropriate permissions and there is enough + space " + "on the storage device."); + */ for (auto lib : version->getActiveNativeLibs()) { + if (!lib->filesExist()) + { + emitFailed("Native library is missing some files:\n" + lib->storagePath() + + "\n\nRun the instance at least once in online mode to get all the " + "required files."); + return; + } if (!lib->extractTo(natives_dir_raw)) { emitFailed("Could not extract the native library:\n" + lib->storagePath() + " to " + natives_dir_raw + - "\nMake sure MultiMC has appropriate permissions and there is enough " + "\n\nMake sure MultiMC has appropriate permissions and there is enough " "space on the storage device."); return; } diff --git a/logic/auth/MojangAccount.cpp b/logic/auth/MojangAccount.cpp index a462eda5..f41985ec 100644 --- a/logic/auth/MojangAccount.cpp +++ b/logic/auth/MojangAccount.cpp @@ -198,7 +198,11 @@ void MojangAccount::authFailed(QString reason) { // This is emitted when the yggdrasil tasks time out or are cancelled. // -> we treat the error as no-op - if (reason != "Yggdrasil task cancelled.") + if (reason == "Yggdrasil task cancelled.") + { + // do nothing + } + else { m_online = false; m_accessToken = QString(); diff --git a/logic/lists/ForgeVersionList.cpp b/logic/lists/ForgeVersionList.cpp index 38e033fa..4902dc64 100644 --- a/logic/lists/ForgeVersionList.cpp +++ b/logic/lists/ForgeVersionList.cpp @@ -187,7 +187,7 @@ bool ForgeListLoadTask::parseForgeList(QList &out) QByteArray data; { auto dlJob = listDownload; - auto filename = std::dynamic_pointer_cast(dlJob)->m_target_path; + auto filename = std::dynamic_pointer_cast(dlJob)->getTargetFilepath(); QFile listFile(filename); if (!listFile.open(QIODevice::ReadOnly)) { @@ -303,7 +303,7 @@ bool ForgeListLoadTask::parseForgeGradleList(QList &out) QByteArray data; { auto dlJob = gradleListDownload; - auto filename = std::dynamic_pointer_cast(dlJob)->m_target_path; + auto filename = std::dynamic_pointer_cast(dlJob)->getTargetFilepath(); QFile listFile(filename); if (!listFile.open(QIODevice::ReadOnly)) { diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 0022c361..d2a9bdee 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -40,7 +40,9 @@ void CacheDownload::start() emit succeeded(m_index_within_job); return; } - m_output_file.setFileName(m_target_path); + // create a new save file + m_output_file.reset(new QSaveFile(m_target_path)); + // if there already is a file and md5 checking is in effect and it can be opened if (!ensureFilePathExists(m_target_path)) { @@ -49,7 +51,7 @@ void CacheDownload::start() emit failed(m_index_within_job); return; } - if (!m_output_file.open(QIODevice::WriteOnly)) + if (!m_output_file->open(QIODevice::WriteOnly)) { QLOG_ERROR() << "Could not open " + m_target_path + " for writing"; m_status = Job_Failed; @@ -94,7 +96,7 @@ void CacheDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) void CacheDownload::downloadError(QNetworkReply::NetworkError error) { // error happened during download. - QLOG_ERROR() << "Failed" << m_url.toString() << "with reason" << error; + QLOG_ERROR() << "Failed " << m_url.toString() << " with reason " << error; m_status = Job_Failed; } void CacheDownload::downloadFinished() @@ -102,17 +104,17 @@ void CacheDownload::downloadFinished() // if the download succeeded if (m_status == Job_Failed) { - m_output_file.cancelWriting(); + m_output_file->cancelWriting(); m_reply.reset(); - m_status = Job_Failed; emit failed(m_index_within_job); return; } + // if we wrote any data to the save file, we try to commit the data to the real file. if (wroteAnyData) { // nothing went wrong... - if (m_output_file.commit()) + if (m_output_file->commit()) { m_status = Job_Finished; m_entry->md5sum = md5sum.result().toHex().constData(); @@ -120,7 +122,7 @@ void CacheDownload::downloadFinished() else { QLOG_ERROR() << "Failed to commit changes to " << m_target_path; - m_output_file.cancelWriting(); + m_output_file->cancelWriting(); m_reply.reset(); m_status = Job_Failed; emit failed(m_index_within_job); @@ -132,6 +134,9 @@ void CacheDownload::downloadFinished() m_status = Job_Finished; } + // then get rid of the save file + m_output_file.reset(); + QFileInfo output_file_info(m_target_path); m_entry->etag = m_reply->rawHeader("ETag").constData(); @@ -153,7 +158,7 @@ void CacheDownload::downloadReadyRead() { QByteArray ba = m_reply->readAll(); md5sum.addData(ba); - if (m_output_file.write(ba) != ba.size()) + if (m_output_file->write(ba) != ba.size()) { QLOG_ERROR() << "Failed writing into " + m_target_path; m_status = Job_Failed; diff --git a/logic/net/CacheDownload.h b/logic/net/CacheDownload.h index 48be1dae..154f5988 100644 --- a/logic/net/CacheDownload.h +++ b/logic/net/CacheDownload.h @@ -24,12 +24,12 @@ typedef std::shared_ptr CacheDownloadPtr; class CacheDownload : public NetAction { Q_OBJECT -public: +private: MetaEntryPtr m_entry; /// if saving to file, use the one specified in this string QString m_target_path; /// this is the output file, if any - QSaveFile m_output_file; + std::shared_ptr m_output_file; /// the hash-as-you-download QCryptographicHash md5sum; @@ -41,7 +41,10 @@ public: { return CacheDownloadPtr(new CacheDownload(url, entry)); } - + QString getTargetFilepath() + { + return m_target_path; + } protected slots: virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); diff --git a/logic/updater/NotificationChecker.cpp b/logic/updater/NotificationChecker.cpp index b2d67632..191e90a3 100644 --- a/logic/updater/NotificationChecker.cpp +++ b/logic/updater/NotificationChecker.cpp @@ -55,7 +55,7 @@ void NotificationChecker::downloadSucceeded(int) { m_entries.clear(); - QFile file(m_download->m_output_file.fileName()); + QFile file(m_download->getTargetFilepath()); if (file.open(QFile::ReadOnly)) { QJsonArray root = QJsonDocument::fromJson(file.readAll()).array(); -- cgit v1.2.3 From 208209e4a73e6ce75b8ecbd40b5cf7c6e9117eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 18 Jan 2014 22:16:47 +0100 Subject: Fix derp: there is no static QFileInfo::exists in Qt 5.1.1 --- logic/OneSixLibrary.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'logic') diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp index cf29a832..510be52b 100644 --- a/logic/OneSixLibrary.cpp +++ b/logic/OneSixLibrary.cpp @@ -143,13 +143,15 @@ bool OneSixLibrary::filesExist() { QString cooked_storage = storage; cooked_storage.replace("${arch}", "32"); - if (!QFileInfo::exists(PathCombine("libraries", cooked_storage))) + QFileInfo info32(PathCombine("libraries", cooked_storage)); + if (!info32.exists()) { return false; } cooked_storage = storage; cooked_storage.replace("${arch}", "64"); - if (!QFileInfo::exists(PathCombine("libraries", cooked_storage))) + QFileInfo info64(PathCombine("libraries", cooked_storage)); + if (!info64.exists()) { return false; } -- cgit v1.2.3 From e9186d6d2c9d5e08516d6a3126440f89e55d056b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 18 Jan 2014 22:20:36 +0100 Subject: DERP DERP DERP DERP ALERT. DUCK AND COVER! --- logic/OneSixLibrary.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'logic') diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp index 510be52b..d1eceb0e 100644 --- a/logic/OneSixLibrary.cpp +++ b/logic/OneSixLibrary.cpp @@ -158,7 +158,8 @@ bool OneSixLibrary::filesExist() } else { - if (!QFileInfo::exists(PathCombine("libraries", storage))) + QFileInfo info(PathCombine("libraries", storage)); + if (!info.exists()) { return false; } -- cgit v1.2.3 From 5eb9ef5d565fcbf00688f24bc83c8b33a76e54a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 19 Jan 2014 23:05:16 +0100 Subject: Scale faces to 64x64 --- logic/SkinUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'logic') diff --git a/logic/SkinUtils.h b/logic/SkinUtils.h index 324f86b8..64353b72 100644 --- a/logic/SkinUtils.h +++ b/logic/SkinUtils.h @@ -19,5 +19,5 @@ namespace SkinUtils { -QPixmap getFaceFromCache(QString username, int height = 48, int width = 48); +QPixmap getFaceFromCache(QString username, int height = 64, int width = 64); } -- cgit v1.2.3 From 3a3c9ac9515447941d383f2c4fe4b0225fdd8252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 20 Jan 2014 01:14:11 +0100 Subject: Update the changelog, version, scale the instance icon --- logic/icons/IconList.cpp | 17 +++++++++++++++++ logic/icons/IconList.h | 1 + 2 files changed, 18 insertions(+) (limited to 'logic') diff --git a/logic/icons/IconList.cpp b/logic/icons/IconList.cpp index cda2db7b..d76e6fbb 100644 --- a/logic/icons/IconList.cpp +++ b/logic/icons/IconList.cpp @@ -336,6 +336,23 @@ QIcon IconList::getIcon(QString key) return QIcon(); } +QIcon IconList::getBigIcon(QString key) +{ + int icon_index = getIconIndex(key); + + if (icon_index == -1) + key = "infinity"; + + // Fallback for icons that don't exist. + icon_index = getIconIndex(key); + + if (icon_index == -1) + return QIcon(); + + QPixmap bigone = icons[icon_index].icon().pixmap(256,256).scaled(256,256); + return QIcon(bigone); +} + int IconList::getIconIndex(QString key) { if (key == "default") diff --git a/logic/icons/IconList.h b/logic/icons/IconList.h index 322411d1..4ee3f782 100644 --- a/logic/icons/IconList.h +++ b/logic/icons/IconList.h @@ -34,6 +34,7 @@ public: virtual ~IconList() {}; QIcon getIcon(QString key); + QIcon getBigIcon(QString key); int getIconIndex(QString key); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; -- cgit v1.2.3