From 06661bff35a963fb4e91d28e6cc3b8ee28503f64 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 8 Sep 2021 19:17:44 +0200 Subject: [PATCH 1/6] NOISSUE: Add notice on support of selfbuilds Add notice that building MultiMC, besides development purposes, is unsupported. --- BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.md b/BUILD.md index f6b66e70..5403b5f3 100644 --- a/BUILD.md +++ b/BUILD.md @@ -15,6 +15,7 @@ MultiMC is a portable application and is not supposed to be installed into any s 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. +Also note that this guide is for development purposes only. No support is given for building your own fork or special build for what reasons what so ever. # Getting the source From d1b111379862fd0906ffca2dae8e570206a326c7 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 8 Sep 2021 20:45:01 +0200 Subject: [PATCH 2/6] Update BUILD.md --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 5403b5f3..de97433b 100644 --- a/BUILD.md +++ b/BUILD.md @@ -15,7 +15,7 @@ MultiMC is a portable application and is not supposed to be installed into any s 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. -Also note that this guide is for development purposes only. No support is given for building your own fork or special build for what reasons what so ever. +Also note that this guide is for development purposes only. No support is given for building your own fork or special build for any reason whatsoever. # Getting the source From 29f304f0703612d56b26d111cf802e145ae5896f Mon Sep 17 00:00:00 2001 From: kb1000 Date: Tue, 14 Sep 2021 12:13:41 +0200 Subject: [PATCH 3/6] Use exec to launch the MultiMC script in the Debian/RPM packages --- launcher/package/ubuntu/multimc/opt/multimc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/package/ubuntu/multimc/opt/multimc/run.sh b/launcher/package/ubuntu/multimc/opt/multimc/run.sh index c493a513..12a9b45c 100755 --- a/launcher/package/ubuntu/multimc/opt/multimc/run.sh +++ b/launcher/package/ubuntu/multimc/opt/multimc/run.sh @@ -22,7 +22,7 @@ deploy() { runmmc() { cd ${INSTDIR} - ./MultiMC "$@" + exec ./MultiMC "$@" } if [[ ! -f ${INSTDIR}/MultiMC ]]; then From 0dcd24a53bd4567ff3572f4a60c639daa5b135ea Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 17 Sep 2021 16:00:43 +0100 Subject: [PATCH 4/6] GH-4055 Don't download multiple files to the same path FTB should fix their metadata, but this should resolve issues downloading their packs at present. --- launcher/modplatform/modpacksch/FTBPackInstallTask.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index f22373bc..2e87a754 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -108,6 +108,10 @@ void PackInstallTask::downloadPack() auto relpath = FS::PathCombine("minecraft", file.path, file.name); auto path = FS::PathCombine(m_stagingPath, relpath); + if (filesToCopy.contains(entry->getFullPath())) { + qWarning() << "Ignoring" << file.url << "as a file of that path is already downloading."; + continue; + } qDebug() << "Will download" << file.url << "to" << path; filesToCopy[entry->getFullPath()] = path; From a5956194df7588c22b6853966dba63dda7cbb7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 21 Sep 2021 22:02:12 +0200 Subject: [PATCH 5/6] NOISSUE Remove Requestor, it is unused --- launcher/minecraft/auth/flows/AuthContext.cpp | 33 ++- libraries/katabasis/CMakeLists.txt | 5 - .../katabasis/include/katabasis/Requestor.h | 79 ------- libraries/katabasis/src/Requestor.cpp | 195 ------------------ 4 files changed, 16 insertions(+), 296 deletions(-) delete mode 100644 libraries/katabasis/include/katabasis/Requestor.h delete mode 100644 libraries/katabasis/src/Requestor.cpp diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp index b4db6c2d..47908b70 100644 --- a/launcher/minecraft/auth/flows/AuthContext.cpp +++ b/launcher/minecraft/auth/flows/AuthContext.cpp @@ -23,7 +23,6 @@ #include "Env.h" using OAuth2 = Katabasis::OAuth2; -using Requestor = AuthRequest; using Activity = Katabasis::Activity; AuthContext::AuthContext(AccountData * data, QObject *parent) : @@ -164,8 +163,8 @@ void AuthContext::doUserAuth() { QNetworkRequest request = QNetworkRequest(QUrl("https://user.auth.xboxlive.com/user/authenticate")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - auto *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onUserAuthDone); + auto *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onUserAuthDone); requestor->post(request, xbox_auth_data.toUtf8()); qDebug() << "First layer of XBox auth ... commencing."; } @@ -358,8 +357,8 @@ void AuthContext::doSTSAuthMinecraft() { QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onSTSAuthMinecraftDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthMinecraftDone); requestor->post(request, xbox_auth_data.toUtf8()); qDebug() << "Getting Minecraft services STS token..."; } @@ -428,8 +427,8 @@ void AuthContext::doMinecraftAuth() { QNetworkRequest request = QNetworkRequest(QUrl("https://api.minecraftservices.com/authentication/login_with_xbox")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onMinecraftAuthDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftAuthDone); requestor->post(request, data.toUtf8()); qDebug() << "Getting Minecraft access token..."; } @@ -518,8 +517,8 @@ void AuthContext::doSTSAuthGeneric() { QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onSTSAuthGenericDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthGenericDone); requestor->post(request, xbox_auth_data.toUtf8()); qDebug() << "Getting generic STS token..."; } @@ -574,8 +573,8 @@ void AuthContext::doXBoxProfile() { request.setRawHeader("Accept", "application/json"); request.setRawHeader("x-xbl-contract-version", "3"); request.setRawHeader("Authorization", QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8()); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onXBoxProfileDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onXBoxProfileDone); requestor->get(request); qDebug() << "Getting Xbox profile..."; } @@ -753,8 +752,8 @@ void AuthContext::doMinecraftProfile() { // request.setRawHeader("Accept", "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onMinecraftProfileDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftProfileDone); requestor->get(request); } @@ -801,8 +800,8 @@ void AuthContext::doMigrationEligibilityCheck() { request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onMigrationEligibilityCheckDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onMigrationEligibilityCheckDone); requestor->get(request); } @@ -853,8 +852,8 @@ void AuthContext::doGetSkin() { auto url = QUrl(m_data->minecraftProfile.skin.url); QNetworkRequest request = QNetworkRequest(url); - Requestor *requestor = new Requestor(this); - connect(requestor, &Requestor::finished, this, &AuthContext::onSkinDone); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onSkinDone); requestor->get(request); } diff --git a/libraries/katabasis/CMakeLists.txt b/libraries/katabasis/CMakeLists.txt index 170bc2c9..2f9cb66d 100644 --- a/libraries/katabasis/CMakeLists.txt +++ b/libraries/katabasis/CMakeLists.txt @@ -28,24 +28,19 @@ find_package(Qt5 COMPONENTS Core Network REQUIRED) set( katabasis_PRIVATE src/OAuth2.cpp - src/JsonResponse.cpp src/JsonResponse.h src/PollServer.cpp src/Reply.cpp src/ReplyServer.cpp - src/Requestor.cpp ) set( katabasis_PUBLIC include/katabasis/OAuth2.h - include/katabasis/Globals.h include/katabasis/PollServer.h include/katabasis/Reply.h include/katabasis/ReplyServer.h - - include/katabasis/Requestor.h include/katabasis/RequestParameter.h ) diff --git a/libraries/katabasis/include/katabasis/Requestor.h b/libraries/katabasis/include/katabasis/Requestor.h deleted file mode 100644 index de8016cb..00000000 --- a/libraries/katabasis/include/katabasis/Requestor.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -#include "Reply.h" - -namespace Katabasis { - -class OAuth2; - -/// Makes authenticated requests. -class Requestor: public QObject { - Q_OBJECT - -public: - explicit Requestor(QNetworkAccessManager *manager, OAuth2 *authenticator, QObject *parent = 0); - ~Requestor(); - -public slots: - int get(const QNetworkRequest &req, int timeout = 60*1000); - int post(const QNetworkRequest &req, const QByteArray &data, int timeout = 60*1000); - - -signals: - - /// Emitted when a request has been completed or failed. - void finished(int id, QNetworkReply::NetworkError error, QByteArray data, QList headers); - - /// Emitted when an upload has progressed. - void uploadProgress(int id, qint64 bytesSent, qint64 bytesTotal); - -protected slots: - /// Handle refresh completion. - void onRefreshFinished(QNetworkReply::NetworkError error); - - /// Handle request finished. - void onRequestFinished(); - - /// Handle request error. - void onRequestError(QNetworkReply::NetworkError error); - - /// Handle ssl errors. - void onSslErrors(QList errors); - - /// Re-try request (after successful token refresh). - void retry(); - - /// Finish the request, emit finished() signal. - void finish(); - - /// Handle upload progress. - void onUploadProgress(qint64 uploaded, qint64 total); - -protected: - int setup(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &verb = QByteArray()); - - enum Status { - Idle, Requesting, ReRequesting - }; - - QNetworkAccessManager *manager_; - OAuth2 *authenticator_; - QNetworkRequest request_; - QByteArray data_; - QNetworkReply *reply_; - Status status_; - int id_; - QNetworkAccessManager::Operation operation_; - QUrl url_; - ReplyList timedReplies_; - QNetworkReply::NetworkError error_; -}; - -} diff --git a/libraries/katabasis/src/Requestor.cpp b/libraries/katabasis/src/Requestor.cpp deleted file mode 100644 index 53d77925..00000000 --- a/libraries/katabasis/src/Requestor.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include - -#include -#include -#include -#include - -#include "katabasis/Requestor.h" -#include "katabasis/OAuth2.h" -#include "katabasis/Globals.h" - -namespace Katabasis { - -Requestor::Requestor(QNetworkAccessManager *manager, OAuth2 *authenticator, QObject *parent): QObject(parent), reply_(NULL), status_(Idle) { - manager_ = manager; - authenticator_ = authenticator; - if (authenticator) { - timedReplies_.setIgnoreSslErrors(authenticator->ignoreSslErrors()); - } - qRegisterMetaType("QNetworkReply::NetworkError"); - connect(authenticator, &OAuth2::refreshFinished, this, &Requestor::onRefreshFinished); -} - -Requestor::~Requestor() { -} - -int Requestor::get(const QNetworkRequest &req, int timeout/* = 60*1000*/) { - if (-1 == setup(req, QNetworkAccessManager::GetOperation)) { - return -1; - } - reply_ = manager_->get(request_); - timedReplies_.add(new Reply(reply_, timeout)); - connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); - connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished())); - connect(reply_, &QNetworkReply::sslErrors, this, &Requestor::onSslErrors); - return id_; -} - -int Requestor::post(const QNetworkRequest &req, const QByteArray &data, int timeout/* = 60*1000*/) { - if (-1 == setup(req, QNetworkAccessManager::PostOperation)) { - return -1; - } - data_ = data; - reply_ = manager_->post(request_, data_); - timedReplies_.add(new Reply(reply_, timeout)); - connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); - connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished())); - connect(reply_, &QNetworkReply::sslErrors, this, &Requestor::onSslErrors); - connect(reply_, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(onUploadProgress(qint64,qint64))); - return id_; -} - -void Requestor::onRefreshFinished(QNetworkReply::NetworkError error) { - if (status_ != Requesting) { - qWarning() << "O2Requestor::onRefreshFinished: No pending request"; - return; - } - if (QNetworkReply::NoError == error) { - QTimer::singleShot(100, this, &Requestor::retry); - } else { - error_ = error; - QTimer::singleShot(10, this, &Requestor::finish); - } -} - -void Requestor::onRequestFinished() { - if (status_ == Idle) { - return; - } - if (reply_ != qobject_cast(sender())) { - return; - } - if (reply_->error() == QNetworkReply::NoError) { - QTimer::singleShot(10, this, SLOT(finish())); - } -} - -void Requestor::onRequestError(QNetworkReply::NetworkError error) { - qWarning() << "O2Requestor::onRequestError: Error" << (int)error; - if (status_ == Idle) { - return; - } - if (reply_ != qobject_cast(sender())) { - return; - } - qWarning() << "O2Requestor::onRequestError: Error string: " << reply_->errorString(); - int httpStatus = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - qWarning() << "O2Requestor::onRequestError: HTTP status" << httpStatus << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); - if ((status_ == Requesting) && (httpStatus == 401)) { - // Call OAuth2::refresh. Note the O2 instance might live in a different thread - if (QMetaObject::invokeMethod(authenticator_, "refresh")) { - return; - } - qCritical() << "O2Requestor::onRequestError: Invoking remote refresh failed"; - } - error_ = error; - QTimer::singleShot(10, this, SLOT(finish())); -} - -void Requestor::onSslErrors(QList errors) { - int i = 1; - for (auto error : errors) { - qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString(); - auto cert = error.certificate(); - qCritical() << "Certificate in question:\n" << cert.toText(); - i++; - } -} - -void Requestor::onUploadProgress(qint64 uploaded, qint64 total) { - if (status_ == Idle) { - qWarning() << "O2Requestor::onUploadProgress: No pending request"; - return; - } - if (reply_ != qobject_cast(sender())) { - return; - } - // Restart timeout because request in progress - Reply *o2Reply = timedReplies_.find(reply_); - if(o2Reply) - o2Reply->start(); - emit uploadProgress(id_, uploaded, total); -} - -int Requestor::setup(const QNetworkRequest &req, QNetworkAccessManager::Operation operation, const QByteArray &verb) { - static int currentId; - - if (status_ != Idle) { - qWarning() << "O2Requestor::setup: Another request pending"; - return -1; - } - - request_ = req; - operation_ = operation; - id_ = currentId++; - url_ = req.url(); - - QUrl url = url_; - request_.setUrl(url); - - if (!verb.isEmpty()) { - request_.setRawHeader(HTTP_HTTP_HEADER, verb); - } - - status_ = Requesting; - error_ = QNetworkReply::NoError; - return id_; -} - -void Requestor::finish() { - QByteArray data; - if (status_ == Idle) { - qWarning() << "O2Requestor::finish: No pending request"; - return; - } - data = reply_->readAll(); - status_ = Idle; - timedReplies_.remove(reply_); - reply_->disconnect(this); - reply_->deleteLater(); - QList headers = reply_->rawHeaderPairs(); - emit finished(id_, error_, data, headers); -} - -void Requestor::retry() { - if (status_ != Requesting) { - qWarning() << "O2Requestor::retry: No pending request"; - return; - } - timedReplies_.remove(reply_); - reply_->disconnect(this); - reply_->deleteLater(); - QUrl url = url_; - request_.setUrl(url); - - status_ = ReRequesting; - switch (operation_) { - case QNetworkAccessManager::GetOperation: - reply_ = manager_->get(request_); - break; - case QNetworkAccessManager::PostOperation: - reply_ = manager_->post(request_, data_); - break; - default: - assert(!"Unspecified operation for request"); - reply_ = manager_->get(request_); - break; - } - timedReplies_.add(reply_); - connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError)), Qt::QueuedConnection); - connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished()), Qt::QueuedConnection); - connect(reply_, SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(onUploadProgress(qint64,qint64))); -} - -} From 0f3cf0595b97e949fd0b943e9e7ae69e1fdc5def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 23 Sep 2021 21:26:56 +0200 Subject: [PATCH 6/6] NOISSUE add shader pack page for instances Only theme with an icon is simple colored, rest is TBD --- launcher/CMakeLists.txt | 1 + launcher/InstancePageProvider.h | 2 + launcher/minecraft/MinecraftInstance.cpp | 16 ++++ launcher/minecraft/MinecraftInstance.h | 3 + launcher/pages/instance/ShaderPackPage.h | 22 +++++ launcher/resources/pe_colored/pe_colored.qrc | 1 + .../pe_colored/scalable/shaderpacks.svg | 83 +++++++++++++++++++ 7 files changed, 128 insertions(+) create mode 100644 launcher/pages/instance/ShaderPackPage.h create mode 100644 launcher/resources/pe_colored/scalable/shaderpacks.svg diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c29ee3e1..14704905 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -653,6 +653,7 @@ SET(MULTIMC_SOURCES pages/instance/VersionPage.h pages/instance/TexturePackPage.h pages/instance/ResourcePackPage.h + pages/instance/ShaderPackPage.h pages/instance/ModFolderPage.cpp pages/instance/ModFolderPage.h pages/instance/NotesPage.cpp diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index 3cb723c4..d45b3f2e 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -9,6 +9,7 @@ #include "pages/instance/ModFolderPage.h" #include "pages/instance/ResourcePackPage.h" #include "pages/instance/TexturePackPage.h" +#include "pages/instance/ShaderPackPage.h" #include "pages/instance/NotesPage.h" #include "pages/instance/ScreenshotsPage.h" #include "pages/instance/InstanceSettingsPage.h" @@ -44,6 +45,7 @@ public: values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods")); values.append(new ResourcePackPage(onesix.get())); values.append(new TexturePackPage(onesix.get())); + values.append(new ShaderPackPage(onesix.get())); values.append(new NotesPage(onesix.get())); values.append(new WorldListPage(onesix.get(), onesix->worldList())); values.append(new ServersPage(onesix)); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 5f3c7244..f86269f0 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -222,6 +222,11 @@ QString MinecraftInstance::texturePacksDir() const return FS::PathCombine(gameRoot(), "texturepacks"); } +QString MinecraftInstance::shaderPacksDir() const +{ + return FS::PathCombine(gameRoot(), "shaderpacks"); +} + QString MinecraftInstance::instanceConfigFolder() const { return FS::PathCombine(gameRoot(), "config"); @@ -1010,6 +1015,17 @@ std::shared_ptr MinecraftInstance::texturePackList() const return m_texture_pack_list; } +std::shared_ptr MinecraftInstance::shaderPackList() const +{ + if (!m_shader_pack_list) + { + m_shader_pack_list.reset(new ResourcePackFolderModel(shaderPacksDir())); + m_shader_pack_list->disableInteraction(isRunning()); + connect(this, &BaseInstance::runningStatusChanged, m_shader_pack_list.get(), &ModFolderModel::disableInteraction); + } + return m_shader_pack_list; +} + std::shared_ptr MinecraftInstance::worldList() const { if (!m_world_list) diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index b55a2776..cdfd350b 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -39,6 +39,7 @@ public: QString jarModsDir() const; QString resourcePacksDir() const; QString texturePacksDir() const; + QString shaderPacksDir() const; QString loaderModsDir() const; QString coreModsDir() const; QString modsCacheLocation() const; @@ -71,6 +72,7 @@ public: std::shared_ptr coreModList() const; std::shared_ptr resourcePackList() const; std::shared_ptr texturePackList() const; + std::shared_ptr shaderPackList() const; std::shared_ptr worldList() const; std::shared_ptr gameOptionsModel() const; @@ -124,6 +126,7 @@ protected: // data mutable std::shared_ptr m_loader_mod_list; mutable std::shared_ptr m_core_mod_list; mutable std::shared_ptr m_resource_pack_list; + mutable std::shared_ptr m_shader_pack_list; mutable std::shared_ptr m_texture_pack_list; mutable std::shared_ptr m_world_list; mutable std::shared_ptr m_game_options; diff --git a/launcher/pages/instance/ShaderPackPage.h b/launcher/pages/instance/ShaderPackPage.h new file mode 100644 index 00000000..36724992 --- /dev/null +++ b/launcher/pages/instance/ShaderPackPage.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ModFolderPage.h" +#include "ui_ModFolderPage.h" + +class ShaderPackPage : public ModFolderPage +{ + Q_OBJECT +public: + explicit ShaderPackPage(MinecraftInstance *instance, QWidget *parent = 0) + : ModFolderPage(instance, instance->shaderPackList(), "shaderpacks", + "shaderpacks", tr("Shader packs"), "Resource-packs", parent) + { + ui->actionView_configs->setVisible(false); + } + virtual ~ShaderPackPage() {} + + virtual bool shouldDisplay() const override + { + return true; + } +}; diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index 4472f5e0..e95d6579 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -30,6 +30,7 @@ scalable/resourcepacks.svg scalable/screenshots.svg scalable/settings.svg + scalable/shaderpacks.svg scalable/status-bad.svg scalable/status-good.svg scalable/status-yellow.svg diff --git a/launcher/resources/pe_colored/scalable/shaderpacks.svg b/launcher/resources/pe_colored/scalable/shaderpacks.svg new file mode 100644 index 00000000..9400b933 --- /dev/null +++ b/launcher/resources/pe_colored/scalable/shaderpacks.svg @@ -0,0 +1,83 @@ + +image/svg+xml + + + + + +