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 0cd3bc1d..49f4af91 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. 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 3bb31b18..5ec93609 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 &list); @@ -155,6 +158,7 @@ private: private: int m_watchLevel = 0; + int totalPlayTime = 0; bool m_dirty = false; QList m_instances; QSet m_groupNameCache; diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index de82fa22..39f18166 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -801,9 +801,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/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 #include #include @@ -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 #include #include +#include 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 605a2844..eacdad52 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 @@ -1326,7 +1328,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 @@ -1525,6 +1526,7 @@ void MainWindow::setSelectedInstanceById(const QString &id) { QModelIndex selectionIndex = proxymodel->mapFromSource(index); view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect); + updateStatusCenter(); } } @@ -1853,6 +1855,7 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, 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(); @@ -1931,3 +1934,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 1aa6448b..20634bb3 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/MultiMC.cpp b/application/MultiMC.cpp index 7c737c43..8d6cd3fb 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -264,6 +264,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); dataPath = xdgDataHome + "/multimc"; adjustedBy += "XDG standard " + dataPath; +#elif defined(Q_OS_MAC) + QDir foo(FS::PathCombine(applicationDirPath(), "../../Data")); + dataPath = foo.absolutePath(); + adjustedBy += "Fallback to special Mac location " + dataPath; #else dataPath = applicationDirPath(); adjustedBy += "Fallback to binary path " + dataPath; @@ -308,6 +312,63 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) return; } +#if defined(Q_OS_MAC) + // move user data to new location if on macOS and it still exists in Contents/MacOS + QDir fi(applicationDirPath()); + QString originalData = fi.absolutePath(); + // if the config file exists in Contents/MacOS, then user data is still there and needs to moved + if (QFileInfo::exists(FS::PathCombine(originalData, "multimc.cfg"))) + { + if (!QFileInfo::exists(FS::PathCombine(originalData, "dontmovemacdata"))) + { + QMessageBox::StandardButton askMoveDialogue; + askMoveDialogue = QMessageBox::question(nullptr, "MultiMC 5", "Would you like to move application data to a new data location? It will improve MultiMC's performance, but if you switch to older versions it will look like instances have disappeared. If you select no, you can migrate later in settings. You should select yes unless you're commonly switching between different versions of MultiMC (eg. develop and stable).", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + if (askMoveDialogue == QMessageBox::Yes) + { + qDebug() << "On macOS and found config file in old location, moving user data..."; + QDir dir; + QStringList dataFiles { + "*.log", // MultiMC-@.log + "accounts.json", + "accounts", + "assets", + "cache", + "icons", + "instances", + "libraries", + "meta", + "metacache", + "mods", + "multimc.cfg", + "themes", + "translations" + }; + QDirIterator files(originalData, dataFiles); + while (files.hasNext()) { + QString filePath(files.next()); + QString fileName(files.fileName()); + if (!dir.rename(filePath, FS::PathCombine(dataPath, fileName))) + { + qWarning() << "Failed to move " << fileName; + } + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + QFile file(originalData + "/dontmovemacdata"); + file.open(QIODevice::WriteOnly); + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + } + } +#endif + /* * Establish the mechanism for communication with an already running MultiMC that uses the same data path. * If there is one, tell it what the user actually wanted to do and exit. 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 - 1.4-2 +- Add xrandr to the dependencies * Tue Dec 08 00:34:35 CET 2020 joshua-stone - Add metainfo.xml for improving package metadata diff --git a/application/pages/global/MultiMCPage.cpp b/application/pages/global/MultiMCPage.cpp index 80d5c544..d383e6ed 100644 --- a/application/pages/global/MultiMCPage.cpp +++ b/application/pages/global/MultiMCPage.cpp @@ -29,6 +29,9 @@ #include "BuildConfig.h" #include "themes/ITheme.h" +#include +#include + // FIXME: possibly move elsewhere enum InstSortMode { @@ -78,6 +81,13 @@ MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCP } connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview())); connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview())); + + //move mac data button + QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); + if (!file.exists()) + { + ui->migrateDataFolderMacBtn->setVisible(false); + } } MultiMCPage::~MultiMCPage() @@ -146,6 +156,13 @@ void MultiMCPage::on_modsDirBrowseBtn_clicked() ui->modsDirTextBox->setText(cooked_dir); } } +void MultiMCPage::on_migrateDataFolderMacBtn_clicked() +{ + QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); + file.remove(); + QProcess::startDetached(qApp->arguments()[0]); + qApp->quit(); +} void MultiMCPage::refreshUpdateChannelList() { diff --git a/application/pages/global/MultiMCPage.h b/application/pages/global/MultiMCPage.h index e81832eb..fae75bf2 100644 --- a/application/pages/global/MultiMCPage.h +++ b/application/pages/global/MultiMCPage.h @@ -67,6 +67,7 @@ slots: void on_instDirBrowseBtn_clicked(); void on_modsDirBrowseBtn_clicked(); void on_iconsDirBrowseBtn_clicked(); + void on_migrateDataFolderMacBtn_clicked(); /*! * Updates the list of update channels in the combo box. diff --git a/application/pages/global/MultiMCPage.ui b/application/pages/global/MultiMCPage.ui index ea034919..4ad20242 100644 --- a/application/pages/global/MultiMCPage.ui +++ b/application/pages/global/MultiMCPage.ui @@ -157,6 +157,13 @@ + + + + Move MultiMC data to new location (will restart MultiMC) + + + diff --git a/application/pages/instance/VersionPage.cpp b/application/pages/instance/VersionPage.cpp index 18c73e7d..20cb2c9f 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 Binary files a/application/resources/MultiMC.ico and b/application/resources/MultiMC.ico differ diff --git a/application/resources/multimc/16x16/patreon.png b/application/resources/multimc/16x16/patreon.png index cde2b326..9150c478 100644 Binary files a/application/resources/multimc/16x16/patreon.png and b/application/resources/multimc/16x16/patreon.png differ diff --git a/application/resources/multimc/22x22/patreon.png b/application/resources/multimc/22x22/patreon.png index b6235ad2..f2c2076c 100644 Binary files a/application/resources/multimc/22x22/patreon.png and b/application/resources/multimc/22x22/patreon.png differ diff --git a/application/resources/multimc/24x24/patreon.png b/application/resources/multimc/24x24/patreon.png index c1da080f..add80668 100644 Binary files a/application/resources/multimc/24x24/patreon.png and b/application/resources/multimc/24x24/patreon.png differ diff --git a/application/resources/multimc/32x32/instances/brick.png b/application/resources/multimc/32x32/instances/brick.png index 0b534366..c324fda0 100644 Binary files a/application/resources/multimc/32x32/instances/brick.png and b/application/resources/multimc/32x32/instances/brick.png differ diff --git a/application/resources/multimc/32x32/instances/diamond.png b/application/resources/multimc/32x32/instances/diamond.png index 376ab901..1eb26469 100644 Binary files a/application/resources/multimc/32x32/instances/diamond.png and b/application/resources/multimc/32x32/instances/diamond.png differ diff --git a/application/resources/multimc/32x32/instances/gold.png b/application/resources/multimc/32x32/instances/gold.png index 9bedda16..593410fa 100644 Binary files a/application/resources/multimc/32x32/instances/gold.png and b/application/resources/multimc/32x32/instances/gold.png differ diff --git a/application/resources/multimc/32x32/instances/iron.png b/application/resources/multimc/32x32/instances/iron.png index 28960782..3e811bd6 100644 Binary files a/application/resources/multimc/32x32/instances/iron.png and b/application/resources/multimc/32x32/instances/iron.png differ diff --git a/application/resources/multimc/32x32/instances/planks.png b/application/resources/multimc/32x32/instances/planks.png index 7fcf8467..a94b7502 100644 Binary files a/application/resources/multimc/32x32/instances/planks.png and b/application/resources/multimc/32x32/instances/planks.png differ diff --git a/application/resources/multimc/32x32/instances/stone.png b/application/resources/multimc/32x32/instances/stone.png index 34f9a751..1b6ef7a4 100644 Binary files a/application/resources/multimc/32x32/instances/stone.png and b/application/resources/multimc/32x32/instances/stone.png differ diff --git a/application/resources/multimc/32x32/patreon.png b/application/resources/multimc/32x32/patreon.png index f5ae8a5e..70085aa1 100644 Binary files a/application/resources/multimc/32x32/patreon.png and b/application/resources/multimc/32x32/patreon.png differ diff --git a/application/resources/multimc/48x48/patreon.png b/application/resources/multimc/48x48/patreon.png index 2708a85a..7aec4d7d 100644 Binary files a/application/resources/multimc/48x48/patreon.png and b/application/resources/multimc/48x48/patreon.png differ diff --git a/application/resources/multimc/64x64/patreon.png b/application/resources/multimc/64x64/patreon.png index 7b4814ec..ef5d690e 100644 Binary files a/application/resources/multimc/64x64/patreon.png and b/application/resources/multimc/64x64/patreon.png 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 10c7a102..a2ca11d8 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; @@ -60,6 +65,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 */ 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 +---- + + +RESOURCES +--------- +GitHub: + +Main website: + +AUTHORS +------- +peterix + +// vim: syntax=asciidoc