aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--BUILD.md4
-rw-r--r--CMakeLists.txt3
-rw-r--r--api/logic/BaseInstance.cpp17
-rw-r--r--api/logic/BaseInstance.h1
-rw-r--r--api/logic/InstanceList.cpp18
-rw-r--r--api/logic/InstanceList.h4
-rw-r--r--api/logic/minecraft/MinecraftInstance.cpp10
-rw-r--r--api/logic/minecraft/OneSixVersionFormat.cpp3
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp13
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.h3
-rw-r--r--api/logic/modplatform/legacy_ftb/PackInstallTask.h1
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp9
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackInstallTask.h3
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.cpp12
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.h5
-rw-r--r--api/logic/modplatform/technic/SolderPackInstallTask.cpp12
-rw-r--r--api/logic/modplatform/technic/SolderPackInstallTask.h5
-rw-r--r--api/logic/net/Download.cpp3
-rw-r--r--api/logic/net/PasteUpload.cpp3
-rw-r--r--api/logic/screenshots/ImgurAlbumCreation.cpp4
-rw-r--r--api/logic/screenshots/ImgurUpload.cpp4
-rw-r--r--api/logic/translations/TranslationsModel.cpp25
-rw-r--r--application/MainWindow.cpp20
-rw-r--r--application/MainWindow.h2
-rw-r--r--application/package/rpm/MultiMC5.spec6
-rw-r--r--application/pages/instance/VersionPage.cpp16
-rw-r--r--application/pages/modplatform/technic/TechnicModel.cpp4
-rw-r--r--application/resources/MultiMC.icobin85182 -> 55224 bytes
-rw-r--r--application/resources/multimc/16x16/patreon.pngbin682 -> 840 bytes
-rw-r--r--application/resources/multimc/22x22/patreon.pngbin976 -> 939 bytes
-rw-r--r--application/resources/multimc/24x24/patreon.pngbin1034 -> 977 bytes
-rw-r--r--application/resources/multimc/32x32/instances/brick.pngbin713 -> 2388 bytes
-rw-r--r--application/resources/multimc/32x32/instances/diamond.pngbin708 -> 2444 bytes
-rw-r--r--application/resources/multimc/32x32/instances/gold.pngbin978 -> 2366 bytes
-rw-r--r--application/resources/multimc/32x32/instances/iron.pngbin532 -> 1772 bytes
-rw-r--r--application/resources/multimc/32x32/instances/planks.pngbin461 -> 2299 bytes
-rw-r--r--application/resources/multimc/32x32/instances/stone.pngbin438 -> 1866 bytes
-rw-r--r--application/resources/multimc/32x32/patreon.pngbin1450 -> 1086 bytes
-rw-r--r--application/resources/multimc/48x48/patreon.pngbin2317 -> 1390 bytes
-rw-r--r--application/resources/multimc/64x64/patreon.pngbin3212 -> 1667 bytes
-rw-r--r--buildconfig/BuildConfig.cpp.in1
-rw-r--r--buildconfig/BuildConfig.h10
-rw-r--r--doc/multimc.1.txt62
44 files changed, 239 insertions, 45 deletions
diff --git a/.gitignore b/.gitignore
index 496c382e..e11168c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ CMakeLists.txt.user.*
/.settings
/.idea
cmake-build-*/
+Debug
# Build dirs
build
diff --git a/BUILD.md b/BUILD.md
index 4360fdde..f6b66e70 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -12,7 +12,7 @@ Build Instructions
# Note
MultiMC is a portable application and is not supposed to be installed into any system folders.
-That would be anything outside your home folder. Before runing `make install`, make sure
+That would be anything outside your home folder. Before running `make install`, make sure
you set the install path to something you have write access to. Never build this under
an administrator/root level account. Don't use `sudo`. It won't work and it's not supposed to work.
@@ -22,7 +22,7 @@ an administrator/root level account. Don't use `sudo`. It won't work and it's no
Clone the source code using git and grab all the submodules:
```
-git clone git@github.com:MultiMC/MultiMC5.git
+git clone https://github.com/MultiMC/MultiMC5.git
git submodule init
git submodule update
```
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcf931c0..5e3d6cea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,9 @@ set(MultiMC_META_URL "https://meta.multimc.org/v1/" CACHE STRING "URL to fetch M
# paste.ee API key
set(MultiMC_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE STRING "API key you can get from paste.ee when you register an account")
+# Imgur API Client ID
+set(MultiMC_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application")
+
# Google analytics ID
set(MultiMC_ANALYTICS_ID "UA-87731965-2" CACHE STRING "ID you can get from Google analytics")
diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp
index cff16631..46b45827 100644
--- a/api/logic/BaseInstance.cpp
+++ b/api/logic/BaseInstance.cpp
@@ -37,6 +37,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("notes", "");
m_settings->registerSetting("lastLaunchTime", 0);
m_settings->registerSetting("totalTimePlayed", 0);
+ m_settings->registerSetting("lastTimePlayed", 0);
// Custom Commands
auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false);
@@ -146,9 +147,12 @@ void BaseInstance::setRunning(bool running)
}
else
{
- qint64 current = settings()->get("totalTimePlayed").toLongLong();
QDateTime timeEnded = QDateTime::currentDateTime();
+
+ qint64 current = settings()->get("totalTimePlayed").toLongLong();
settings()->set("totalTimePlayed", current + m_timeStarted.secsTo(timeEnded));
+ settings()->set("lastTimePlayed", m_timeStarted.secsTo(timeEnded));
+
emit propertiesChanged(this);
}
@@ -166,9 +170,20 @@ int64_t BaseInstance::totalTimePlayed() const
return current;
}
+int64_t BaseInstance::lastTimePlayed() const
+{
+ if(m_isRunning)
+ {
+ QDateTime timeNow = QDateTime::currentDateTime();
+ return m_timeStarted.secsTo(timeNow);
+ }
+ return settings()->get("lastTimePlayed").toLongLong();
+}
+
void BaseInstance::resetTimePlayed()
{
settings()->reset("totalTimePlayed");
+ settings()->reset("lastTimePlayed");
}
QString BaseInstance::instanceType() const
diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h
index 64de4bb3..d250e03e 100644
--- a/api/logic/BaseInstance.h
+++ b/api/logic/BaseInstance.h
@@ -87,6 +87,7 @@ public:
void setRunning(bool running);
bool isRunning() const;
int64_t totalTimePlayed() const;
+ int64_t lastTimePlayed() const;
void resetTimePlayed();
/// get the type of this instance
diff --git a/api/logic/InstanceList.cpp b/api/logic/InstanceList.cpp
index 02fae6ac..cb38853b 100644
--- a/api/logic/InstanceList.cpp
+++ b/api/logic/InstanceList.cpp
@@ -387,9 +387,19 @@ InstanceList::InstListError InstanceList::loadList()
add(newList);
}
m_dirty = false;
+ updateTotalPlayTime();
return NoError;
}
+void InstanceList::updateTotalPlayTime()
+{
+ totalPlayTime = 0;
+ for(auto const& itr : m_instances)
+ {
+ totalPlayTime += itr.get()->totalTimePlayed();
+ }
+}
+
void InstanceList::saveNow()
{
for(auto & item: m_instances)
@@ -475,6 +485,7 @@ void InstanceList::propertiesChanged(BaseInstance *inst)
if (i != -1)
{
emit dataChanged(index(i), index(i));
+ updateTotalPlayTime();
}
}
@@ -848,4 +859,9 @@ bool InstanceList::destroyStagingPath(const QString& keyPath)
return FS::deletePath(keyPath);
}
-#include "InstanceList.moc" \ No newline at end of file
+int InstanceList::getTotalPlayTime() {
+ updateTotalPlayTime();
+ return totalPlayTime;
+}
+
+#include "InstanceList.moc"
diff --git a/api/logic/InstanceList.h b/api/logic/InstanceList.h
index 8215cb66..56ee3be4 100644
--- a/api/logic/InstanceList.h
+++ b/api/logic/InstanceList.h
@@ -128,6 +128,8 @@ public:
*/
bool destroyStagingPath(const QString & keyPath);
+ int getTotalPlayTime();
+
signals:
void dataIsInvalid();
void instancesChanged();
@@ -145,6 +147,7 @@ private slots:
private:
int getInstIndex(BaseInstance *inst) const;
+ void updateTotalPlayTime();
void suspendWatch();
void resumeWatch();
void add(const QList<InstancePtr> &list);
@@ -155,6 +158,7 @@ private:
private:
int m_watchLevel = 0;
+ int totalPlayTime = 0;
bool m_dirty = false;
QList<InstancePtr> m_instances;
QSet<QString> m_groupNameCache;
diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp
index ea1e47b6..dbf9f816 100644
--- a/api/logic/minecraft/MinecraftInstance.cpp
+++ b/api/logic/minecraft/MinecraftInstance.cpp
@@ -798,9 +798,15 @@ QString MinecraftInstance::getStatusbarDescription()
QString description;
description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName()));
- if(m_settings->get("ShowGameTime").toBool() && totalTimePlayed() > 0)
+ if(m_settings->get("ShowGameTime").toBool())
{
- description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
+ if (lastTimePlayed() > 0) {
+ description.append(tr(", last played for %1").arg(prettifyTimeDuration(lastTimePlayed())));
+ }
+
+ if (totalTimePlayed() > 0) {
+ description.append(tr(", total played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
+ }
}
if(hasCrashed())
{
diff --git a/api/logic/minecraft/OneSixVersionFormat.cpp b/api/logic/minecraft/OneSixVersionFormat.cpp
index d6aaa790..0329d70e 100644
--- a/api/logic/minecraft/OneSixVersionFormat.cpp
+++ b/api/logic/minecraft/OneSixVersionFormat.cpp
@@ -194,8 +194,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
LibDLInfo->artifact = out->mojangDownloads["client"];
lib->setMojangDownloadInfo(LibDLInfo);
}
- // we got nothing... guess based on ancient hardcoded Mojang behaviour
- // FIXME: this will eventually break...
+ // we got nothing...
else
{
out->addProblem(
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
index dac80e8c..55087a27 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
@@ -28,7 +28,11 @@ PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString pack,
bool PackInstallTask::abort()
{
- return true;
+ if(abortable)
+ {
+ return jobPtr->abort();
+ }
+ return false;
}
void PackInstallTask::executeTask()
@@ -418,16 +422,19 @@ void PackInstallTask::installConfigs()
connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
{
+ abortable = false;
jobPtr.reset();
extractConfigs();
});
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
{
+ abortable = false;
jobPtr.reset();
emitFailed(reason);
});
connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
{
+ abortable = true;
setProgress(current, total);
});
@@ -576,11 +583,13 @@ void PackInstallTask::downloadMods()
connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded);
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
{
+ abortable = false;
jobPtr.reset();
emitFailed(reason);
});
connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
{
+ abortable = true;
setProgress(current, total);
});
@@ -588,6 +597,8 @@ void PackInstallTask::downloadMods()
}
void PackInstallTask::onModsDownloaded() {
+ abortable = false;
+
qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId();
jobPtr.reset();
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
index 8233c376..15fd9b32 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
@@ -39,6 +39,7 @@ public:
explicit PackInstallTask(UserInteractionSupport *support, QString pack, QString version);
virtual ~PackInstallTask(){}
+ bool canAbort() const override { return true; }
bool abort() override;
protected:
@@ -72,6 +73,8 @@ private:
private:
UserInteractionSupport *m_support;
+ bool abortable = false;
+
NetJobPtr jobPtr;
QByteArray response;
diff --git a/api/logic/modplatform/legacy_ftb/PackInstallTask.h b/api/logic/modplatform/legacy_ftb/PackInstallTask.h
index 7868d1c4..f3515781 100644
--- a/api/logic/modplatform/legacy_ftb/PackInstallTask.h
+++ b/api/logic/modplatform/legacy_ftb/PackInstallTask.h
@@ -20,6 +20,7 @@ public:
explicit PackInstallTask(Modpack pack, QString version);
virtual ~PackInstallTask(){}
+ bool canAbort() const override { return true; }
bool abort() override;
protected:
diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp b/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
index 6067c56a..f22373bc 100644
--- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -19,7 +19,11 @@ PackInstallTask::PackInstallTask(Modpack pack, QString version)
bool PackInstallTask::abort()
{
- return true;
+ if(abortable)
+ {
+ return jobPtr->abort();
+ }
+ return false;
}
void PackInstallTask::executeTask()
@@ -117,16 +121,19 @@ void PackInstallTask::downloadPack()
connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
{
+ abortable = false;
jobPtr.reset();
install();
});
connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
{
+ abortable = false;
jobPtr.reset();
emitFailed(reason);
});
connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
{
+ abortable = true;
setProgress(current, total);
});
diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h b/api/logic/modplatform/modpacksch/FTBPackInstallTask.h
index 3b2d60de..55db3d3c 100644
--- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h
+++ b/api/logic/modplatform/modpacksch/FTBPackInstallTask.h
@@ -16,6 +16,7 @@ public:
explicit PackInstallTask(Modpack pack, QString version);
virtual ~PackInstallTask(){}
+ bool canAbort() const override { return true; }
bool abort() override;
protected:
@@ -30,6 +31,8 @@ private:
void install();
private:
+ bool abortable = false;
+
NetJobPtr jobPtr;
QByteArray response;
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
index 96e1804d..dbce8e53 100644
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
+++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
@@ -28,6 +28,14 @@ Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUr
m_minecraftVersion = minecraftVersion;
}
+bool Technic::SingleZipPackInstallTask::abort() {
+ if(m_abortable)
+ {
+ return m_filesNetJob->abort();
+ }
+ return false;
+}
+
void Technic::SingleZipPackInstallTask::executeTask()
{
setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));
@@ -47,6 +55,8 @@ void Technic::SingleZipPackInstallTask::executeTask()
void Technic::SingleZipPackInstallTask::downloadSucceeded()
{
+ m_abortable = false;
+
setStatus(tr("Extracting modpack"));
QDir extractDir(FS::PathCombine(m_stagingPath, ".minecraft"));
qDebug() << "Attempting to create instance from" << m_archivePath;
@@ -67,12 +77,14 @@ void Technic::SingleZipPackInstallTask::downloadSucceeded()
void Technic::SingleZipPackInstallTask::downloadFailed(QString reason)
{
+ m_abortable = false;
emitFailed(reason);
m_filesNetJob.reset();
}
void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current, qint64 total)
{
+ m_abortable = true;
setProgress(current / 2, total);
}
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.h b/api/logic/modplatform/technic/SingleZipPackInstallTask.h
index c56b9e46..ec2ff605 100644
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.h
+++ b/api/logic/modplatform/technic/SingleZipPackInstallTask.h
@@ -36,6 +36,9 @@ class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask
public:
SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion);
+ bool canAbort() const override { return true; }
+ bool abort() override;
+
protected:
void executeTask() override;
@@ -48,6 +51,8 @@ private slots:
void extractAborted();
private:
+ bool m_abortable = false;
+
QUrl m_sourceUrl;
QString m_minecraftVersion;
QString m_archivePath;
diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.cpp b/api/logic/modplatform/technic/SolderPackInstallTask.cpp
index 1d17073c..1b4186d4 100644
--- a/api/logic/modplatform/technic/SolderPackInstallTask.cpp
+++ b/api/logic/modplatform/technic/SolderPackInstallTask.cpp
@@ -27,6 +27,14 @@ Technic::SolderPackInstallTask::SolderPackInstallTask(const QUrl &sourceUrl, con
m_minecraftVersion = minecraftVersion;
}
+bool Technic::SolderPackInstallTask::abort() {
+ if(m_abortable)
+ {
+ return m_filesNetJob->abort();
+ }
+ return false;
+}
+
void Technic::SolderPackInstallTask::executeTask()
{
setStatus(tr("Finding recommended version:\n%1").arg(m_sourceUrl.toString()));
@@ -106,6 +114,8 @@ void Technic::SolderPackInstallTask::fileListSucceeded()
void Technic::SolderPackInstallTask::downloadSucceeded()
{
+ m_abortable = false;
+
setStatus(tr("Extracting modpack"));
m_filesNetJob.reset();
m_extractFuture = QtConcurrent::run([this]()
@@ -132,12 +142,14 @@ void Technic::SolderPackInstallTask::downloadSucceeded()
void Technic::SolderPackInstallTask::downloadFailed(QString reason)
{
+ m_abortable = false;
emitFailed(reason);
m_filesNetJob.reset();
}
void Technic::SolderPackInstallTask::downloadProgressChanged(qint64 current, qint64 total)
{
+ m_abortable = true;
setProgress(current / 2, total);
}
diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.h b/api/logic/modplatform/technic/SolderPackInstallTask.h
index 0fe6cb83..9f0f20a9 100644
--- a/api/logic/modplatform/technic/SolderPackInstallTask.h
+++ b/api/logic/modplatform/technic/SolderPackInstallTask.h
@@ -29,6 +29,9 @@ namespace Technic
public:
explicit SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion);
+ bool canAbort() const override { return true; }
+ bool abort() override;
+
protected:
//! Entry point for tasks.
virtual void executeTask() override;
@@ -43,6 +46,8 @@ namespace Technic
void extractAborted();
private:
+ bool m_abortable = false;
+
NetJobPtr m_filesNetJob;
QUrl m_sourceUrl;
QString m_minecraftVersion;
diff --git a/api/logic/net/Download.cpp b/api/logic/net/Download.cpp
index 340f8657..3f183b7d 100644
--- a/api/logic/net/Download.cpp
+++ b/api/logic/net/Download.cpp
@@ -15,6 +15,7 @@
#include "Download.h"
+#include "BuildConfig.h"
#include <QFileInfo>
#include <QDateTime>
#include <QDebug>
@@ -94,7 +95,7 @@ void Download::start()
return;
}
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0");
+ request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT);
QNetworkReply *rep = ENV.qnam().get(request);
diff --git a/api/logic/net/PasteUpload.cpp b/api/logic/net/PasteUpload.cpp
index 3526e207..cb470c49 100644
--- a/api/logic/net/PasteUpload.cpp
+++ b/api/logic/net/PasteUpload.cpp
@@ -5,6 +5,7 @@
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
+#include <BuildConfig.h>
PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window)
{
@@ -34,7 +35,7 @@ bool PasteUpload::validateText()
void PasteUpload::executeTask()
{
QNetworkRequest request(QUrl("https://api.paste.ee/v1/pastes"));
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
+ request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED);
request.setRawHeader("Content-Type", "application/json");
request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size()));
diff --git a/api/logic/screenshots/ImgurAlbumCreation.cpp b/api/logic/screenshots/ImgurAlbumCreation.cpp
index ff9ec6fd..1f195f00 100644
--- a/api/logic/screenshots/ImgurAlbumCreation.cpp
+++ b/api/logic/screenshots/ImgurAlbumCreation.cpp
@@ -20,9 +20,9 @@ void ImgurAlbumCreation::start()
{
m_status = Job_InProgress;
QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
+ request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
+ request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str());
request.setRawHeader("Accept", "application/json");
QStringList hashes;
diff --git a/api/logic/screenshots/ImgurUpload.cpp b/api/logic/screenshots/ImgurUpload.cpp
index 1585b061..7e95d5ca 100644
--- a/api/logic/screenshots/ImgurUpload.cpp
+++ b/api/logic/screenshots/ImgurUpload.cpp
@@ -23,8 +23,8 @@ void ImgurUpload::start()
finished = false;
m_status = Job_InProgress;
QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
+ request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED);
+ request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str());
request.setRawHeader("Accept", "application/json");
QFile f(m_shot->m_file.absoluteFilePath());
diff --git a/api/logic/translations/TranslationsModel.cpp b/api/logic/translations/TranslationsModel.cpp
index 401b64d4..29a952b0 100644
--- a/api/logic/translations/TranslationsModel.cpp
+++ b/api/logic/translations/TranslationsModel.cpp
@@ -17,18 +17,6 @@
const static QLatin1Literal defaultLangCode("en_US");
-static QLocale getLocaleFromKey(const QString &key) {
- if(key == "pt") {
- return QLocale("pt_PT");
- }
- else if (key == "en") {
- return QLocale("en_GB");
- }
- else {
- return QLocale(key);
- }
-}
-
enum class FileType
{
NONE,
@@ -45,7 +33,7 @@ struct Language
Language(const QString & _key)
{
key = _key;
- locale = getLocaleFromKey(key);
+ locale = QLocale(key);
updated = (key == defaultLangCode);
}
@@ -310,11 +298,14 @@ void TranslationsModel::reloadLocalFiles()
{
return;
}
- beginInsertRows(QModelIndex(), d->m_languages.size(), d->m_languages.size() + languages.size() - 1);
+ beginInsertRows(QModelIndex(), 0, d->m_languages.size() + languages.size() - 1);
for(auto & language: languages)
{
d->m_languages.append(language);
}
+ std::sort(d->m_languages.begin(), d->m_languages.end(), [](const Language& a, const Language& b) {
+ return a.key.compare(b.key) < 0;
+ });
endInsertRows();
}
@@ -347,7 +338,7 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const
{
case Column::Language:
{
- return d->m_languages[row].locale.nativeLanguageName();
+ return lang.locale.nativeLanguageName();
}
case Column::Completeness:
{
@@ -362,7 +353,7 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const
return tr("%1:\n%2 translated\n%3 fuzzy\n%4 total").arg(lang.key, QString::number(lang.translated), QString::number(lang.fuzzy), QString::number(lang.total));
}
case Qt::UserRole:
- return d->m_languages[row].key;
+ return lang.key;
default:
return QVariant();
}
@@ -459,7 +450,7 @@ bool TranslationsModel::selectLanguage(QString key)
* In a multithreaded application, the default locale should be set at application startup, before any non-GUI threads are created.
* This function is not reentrant.
*/
- QLocale locale = getLocaleFromKey(langCode);
+ QLocale locale = QLocale(langCode);
QLocale::setDefault(locale);
// if it's the default UI language, finish
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index 13a7c7ae..9225193e 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -724,8 +724,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow
connect(MMC, &MultiMC::globalSettingsClosed, this, &MainWindow::globalSettingsClosed);
m_statusLeft = new QLabel(tr("No instance selected"), this);
+ m_statusCenter = new QLabel(tr("Total playtime: 0s."), this);
m_statusRight = new ServerStatus(this);
statusBar()->addPermanentWidget(m_statusLeft, 1);
+ statusBar()->addPermanentWidget(m_statusCenter, 1);
statusBar()->addPermanentWidget(m_statusRight, 0);
// Add "manage accounts" button, right align
@@ -1327,7 +1329,6 @@ void MainWindow::setCatBackground(bool enabled)
{
QDateTime now = QDateTime::currentDateTime();
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- ;
QString cat = (non_stupid_abs(now.daysTo(xmas)) <= 4) ? "catmas" : "kitteh";
view->setStyleSheet(QString(R"(
GroupView
@@ -1526,6 +1527,7 @@ void MainWindow::setSelectedInstanceById(const QString &id)
{
QModelIndex selectionIndex = proxymodel->mapFromSource(index);
view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect);
+ updateStatusCenter();
}
}
@@ -1854,6 +1856,7 @@ void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &
ui->actionExportInstance->setEnabled(m_selectedInstance->canExport());
ui->renameButton->setText(m_selectedInstance->name());
m_statusLeft->setText(m_selectedInstance->getStatusbarDescription());
+ updateStatusCenter();
updateInstanceToolIcon(m_selectedInstance->iconKey());
updateToolsMenu();
@@ -1932,3 +1935,18 @@ void MainWindow::checkInstancePathForProblems()
warning.exec();
}
}
+
+void MainWindow::updateStatusCenter()
+{
+ int timeplayed = MMC->instances()->getTotalPlayTime();
+ int minutesTotal = timeplayed / 60;
+ int seconds = timeplayed % 60;
+ int minutes = minutesTotal % 60;
+ int hours = minutesTotal / 60;
+ if(hours != 0)
+ m_statusCenter->setText(tr("Total playtime: %1h %2m %3s").arg(hours).arg(minutes).arg(seconds));
+ else if(minutes != 0)
+ m_statusCenter->setText(tr("Total playtime: %1m %2s").arg(minutes).arg(seconds));
+ else if(seconds != 0)
+ m_statusCenter->setText(tr("Total playtime: %1s").arg(seconds));
+}
diff --git a/application/MainWindow.h b/application/MainWindow.h
index 08c6b969..c992ab94 100644
--- a/application/MainWindow.h
+++ b/application/MainWindow.h
@@ -194,6 +194,7 @@ private:
void setCatBackground(bool enabled);
void updateInstanceToolIcon(QString new_icon);
void setSelectedInstanceById(const QString &id);
+ void updateStatusCenter();
void runModalTask(Task *task);
void instanceFromInstanceTask(InstanceTask *task);
@@ -207,6 +208,7 @@ private:
InstanceProxyModel *proxymodel = nullptr;
QToolButton *newsLabel = nullptr;
QLabel *m_statusLeft = nullptr;
+ QLabel *m_statusCenter = nullptr;
ServerStatus *m_statusRight = nullptr;
QMenu *accountMenu = nullptr;
QToolButton *accountMenuButton = nullptr;
diff --git a/application/package/rpm/MultiMC5.spec b/application/package/rpm/MultiMC5.spec
index 5b72c781..78b9000e 100644
--- a/application/package/rpm/MultiMC5.spec
+++ b/application/package/rpm/MultiMC5.spec
@@ -1,13 +1,13 @@
Name: MultiMC5
Version: 1.4
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: A local install wrapper for MultiMC
License: ASL 2.0
URL: https://multimc.org
BuildArch: x86_64
-Requires: zenity qt5-qtbase wget
+Requires: zenity qt5-qtbase wget xrandr
Provides: multimc MultiMC multimc5
%description
@@ -37,6 +37,8 @@ install -m 0644 ../ubuntu/multimc/usr/share/metainfo/multimc.metainfo.xml %{buil
%changelog
+* Tue Jun 01 2021 kb1000 <fedora@kb1000.de> - 1.4-2
+- Add xrandr to the dependencies
* Tue Dec 08 00:34:35 CET 2020 joshua-stone <joshua.gage.stone@gmail.com>
- Add metainfo.xml for improving package metadata
diff --git a/application/pages/instance/VersionPage.cpp b/application/pages/instance/VersionPage.cpp
index eff12c9c..a98bfb7d 100644
--- a/application/pages/instance/VersionPage.cpp
+++ b/application/pages/instance/VersionPage.cpp
@@ -212,12 +212,16 @@ void VersionPage::updateVersionControls()
{
// FIXME: this is a dirty hack
auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft"));
- bool newCraft = minecraftVersion >= Version("1.14");
- bool oldCraft = minecraftVersion <= Version("1.12.2");
- ui->actionInstall_Fabric->setEnabled(controlsEnabled && newCraft);
- ui->actionInstall_Forge->setEnabled(controlsEnabled);
- ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && oldCraft);
- ui->actionReload->setEnabled(true);
+
+ bool supportsFabric = minecraftVersion >= Version("1.14");
+ ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric);
+
+ bool supportsForge = minecraftVersion <= Version("1.16.5");
+ ui->actionInstall_Forge->setEnabled(controlsEnabled && supportsForge);
+
+ bool supportsLiteLoader = minecraftVersion <= Version("1.12.2");
+ ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && supportsLiteLoader);
+
updateButtons();
}
diff --git a/application/pages/modplatform/technic/TechnicModel.cpp b/application/pages/modplatform/technic/TechnicModel.cpp
index a240a94a..def30783 100644
--- a/application/pages/modplatform/technic/TechnicModel.cpp
+++ b/application/pages/modplatform/technic/TechnicModel.cpp
@@ -95,9 +95,7 @@ void Technic::ListModel::performSearch()
NetJob *netJob = new NetJob("Technic::Search");
QString searchUrl = "";
if (currentSearchTerm.isEmpty()) {
- searchUrl = QString(
- "https://api.technicpack.net/trending?build=multimc"
- ).arg(currentSearchTerm);
+ searchUrl = "https://api.technicpack.net/trending?build=multimc";
}
else
{
diff --git a/application/resources/MultiMC.ico b/application/resources/MultiMC.ico
index 1846964e..a86a1f0d 100644
--- a/application/resources/MultiMC.ico
+++ b/application/resources/MultiMC.ico
Binary files differ
diff --git a/application/resources/multimc/16x16/patreon.png b/application/resources/multimc/16x16/patreon.png
index cde2b326..9150c478 100644
--- a/application/resources/multimc/16x16/patreon.png
+++ b/application/resources/multimc/16x16/patreon.png
Binary files differ
diff --git a/application/resources/multimc/22x22/patreon.png b/application/resources/multimc/22x22/patreon.png
index b6235ad2..f2c2076c 100644
--- a/application/resources/multimc/22x22/patreon.png
+++ b/application/resources/multimc/22x22/patreon.png
Binary files differ
diff --git a/application/resources/multimc/24x24/patreon.png b/application/resources/multimc/24x24/patreon.png
index c1da080f..add80668 100644
--- a/application/resources/multimc/24x24/patreon.png
+++ b/application/resources/multimc/24x24/patreon.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/brick.png b/application/resources/multimc/32x32/instances/brick.png
index 0b534366..c324fda0 100644
--- a/application/resources/multimc/32x32/instances/brick.png
+++ b/application/resources/multimc/32x32/instances/brick.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/diamond.png b/application/resources/multimc/32x32/instances/diamond.png
index 376ab901..1eb26469 100644
--- a/application/resources/multimc/32x32/instances/diamond.png
+++ b/application/resources/multimc/32x32/instances/diamond.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/gold.png b/application/resources/multimc/32x32/instances/gold.png
index 9bedda16..593410fa 100644
--- a/application/resources/multimc/32x32/instances/gold.png
+++ b/application/resources/multimc/32x32/instances/gold.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/iron.png b/application/resources/multimc/32x32/instances/iron.png
index 28960782..3e811bd6 100644
--- a/application/resources/multimc/32x32/instances/iron.png
+++ b/application/resources/multimc/32x32/instances/iron.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/planks.png b/application/resources/multimc/32x32/instances/planks.png
index 7fcf8467..a94b7502 100644
--- a/application/resources/multimc/32x32/instances/planks.png
+++ b/application/resources/multimc/32x32/instances/planks.png
Binary files differ
diff --git a/application/resources/multimc/32x32/instances/stone.png b/application/resources/multimc/32x32/instances/stone.png
index 34f9a751..1b6ef7a4 100644
--- a/application/resources/multimc/32x32/instances/stone.png
+++ b/application/resources/multimc/32x32/instances/stone.png
Binary files differ
diff --git a/application/resources/multimc/32x32/patreon.png b/application/resources/multimc/32x32/patreon.png
index f5ae8a5e..70085aa1 100644
--- a/application/resources/multimc/32x32/patreon.png
+++ b/application/resources/multimc/32x32/patreon.png
Binary files differ
diff --git a/application/resources/multimc/48x48/patreon.png b/application/resources/multimc/48x48/patreon.png
index 2708a85a..7aec4d7d 100644
--- a/application/resources/multimc/48x48/patreon.png
+++ b/application/resources/multimc/48x48/patreon.png
Binary files differ
diff --git a/application/resources/multimc/64x64/patreon.png b/application/resources/multimc/64x64/patreon.png
index 7b4814ec..ef5d690e 100644
--- a/application/resources/multimc/64x64/patreon.png
+++ b/application/resources/multimc/64x64/patreon.png
Binary files differ
diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in
index 577bdcb2..60d417a6 100644
--- a/buildconfig/BuildConfig.cpp.in
+++ b/buildconfig/BuildConfig.cpp.in
@@ -33,6 +33,7 @@ Config::Config()
VERSION_STR = "@MultiMC_VERSION_STRING@";
NEWS_RSS_URL = "@MultiMC_NEWS_RSS_URL@";
PASTE_EE_KEY = "@MultiMC_PASTE_EE_API_KEY@";
+ IMGUR_CLIENT_ID = "@MultiMC_IMGUR_CLIENT_ID@";
META_URL = "@MultiMC_META_URL@";
BUG_TRACKER_URL = "@MultiMC_BUG_TRACKER_URL@";
diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h
index 66d05ae0..185bebad 100644
--- a/buildconfig/BuildConfig.h
+++ b/buildconfig/BuildConfig.h
@@ -31,6 +31,11 @@ public:
/// URL for the updater's channel
QString CHANLIST_URL;
+ /// User-Agent to use.
+ QString USER_AGENT = "MultiMC/5.0";
+ /// User-Agent to use for uncached requests.
+ QString USER_AGENT_UNCACHED = "MultiMC/5.0 (Uncached)";
+
/// Google analytics ID
QString ANALYTICS_ID;
@@ -61,6 +66,11 @@ public:
QString PASTE_EE_KEY;
/**
+ * Client ID you can get from Imgur when you register an application
+ */
+ QString IMGUR_CLIENT_ID;
+
+ /**
* MultiMC Metadata repository URL prefix
*/
QString META_URL;
diff --git a/doc/multimc.1.txt b/doc/multimc.1.txt
new file mode 100644
index 00000000..c2d93880
--- /dev/null
+++ b/doc/multimc.1.txt
@@ -0,0 +1,62 @@
+MULTIMC(1)
+==========
+:doctype: manpage
+
+
+NAME
+----
+multimc - a launcher and instance manager for Minecraft.
+
+
+SYNOPSIS
+--------
+*multimc* ['OPTIONS']
+
+
+DESCRIPTION
+-----------
+MultiMC is a custom launcher for Minecraft that allows you to easily manage
+multiple installations of Minecraft at once. It also allows you to easily
+install and remove mods by simply dragging and dropping.
+Here are the current features of MultiMC.
+
+OPTIONS
+-------
+*-d, --dir*='DIRECTORY'::
+ Use 'DIRECTORY' as the MultiMC root.
+
+*-l, --launch*='INSTANCE_ID'::
+ Launch the instance specified by 'INSTANCE_ID'.
+
+*--alive*::
+ Write a small 'live.check' file after MultiMC starts.
+
+*-h, --help*::
+ Display help text and exit.
+
+*-v, --version*::
+ Display program version and exit.
+
+EXIT STATUS
+-----------
+*0*::
+ Success
+
+*1*::
+ Failure (syntax or usage error; configuration error; unexpected error).
+
+BUGS
+----
+<https://github.com/MultiMC/MultiMC5/issues>
+
+RESOURCES
+---------
+GitHub: <https://github.com/MultiMC/MultiMC5>
+
+Main website: <https://multimc.org>
+
+AUTHORS
+-------
+peterix <peterix@gmail.com>
+
+// vim: syntax=asciidoc