diff options
32 files changed, 546 insertions, 307 deletions
@@ -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 any reason whatsoever. # Getting the source 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<ModFolderModel> MinecraftInstance::texturePackList() const return m_texture_pack_list; } +std::shared_ptr<ModFolderModel> 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<WorldList> 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<ModFolderModel> coreModList() const; std::shared_ptr<ModFolderModel> resourcePackList() const; std::shared_ptr<ModFolderModel> texturePackList() const; + std::shared_ptr<ModFolderModel> shaderPackList() const; std::shared_ptr<WorldList> worldList() const; std::shared_ptr<GameOptions> gameOptionsModel() const; @@ -124,6 +126,7 @@ protected: // data mutable std::shared_ptr<ModFolderModel> m_loader_mod_list; mutable std::shared_ptr<ModFolderModel> m_core_mod_list; mutable std::shared_ptr<ModFolderModel> m_resource_pack_list; + mutable std::shared_ptr<ModFolderModel> m_shader_pack_list; mutable std::shared_ptr<ModFolderModel> m_texture_pack_list; mutable std::shared_ptr<WorldList> m_world_list; mutable std::shared_ptr<GameOptions> m_game_options; diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp index 961057ca..9fb3ec48 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/launcher/minecraft/auth/flows/Yggdrasil.cpp b/launcher/minecraft/auth/flows/Yggdrasil.cpp index c2935d05..ce828fd4 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.cpp +++ b/launcher/minecraft/auth/flows/Yggdrasil.cpp @@ -243,9 +243,7 @@ void Yggdrasil::processReply() STATE_FAILED_SOFT, tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>" "<ul>" - "<li>You use Windows XP and need to <a " - "href=\"https://www.microsoft.com/en-us/download/details.aspx?id=38918\">update " - "your root certificates</a></li>" + "<li>You use Windows and need to update your root certificates, please install any outstanding updates.</li>" "<li>Some device on your network is interfering with SSL traffic. In that case, " "you have bigger worries than Minecraft not starting.</li>" "<li>Possibly something else. Check the MultiMC log file for details</li>" diff --git a/launcher/minecraft/update/FMLLibrariesTask.cpp b/launcher/minecraft/update/FMLLibrariesTask.cpp index a05a7c2a..8f1a43ff 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.cpp +++ b/launcher/minecraft/update/FMLLibrariesTask.cpp @@ -58,7 +58,7 @@ void FMLLibrariesTask::executeTask() } // download missing libs to our place - setStatus(tr("Dowloading FML libraries...")); + setStatus(tr("Downloading FML libraries...")); auto dljob = new NetJob("FML libraries"); auto metacache = ENV.metacache(); for (auto &lib : fmlLibsToProcess) diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index f22373bc..496edde7 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -108,8 +108,12 @@ void PackInstallTask::downloadPack() auto relpath = FS::PathCombine("minecraft", file.path, file.name); auto path = FS::PathCombine(m_stagingPath, relpath); + if (filesToCopy.contains(path)) { + 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; + filesToCopy[path] = entry->getFullPath(); auto dl = Net::Download::makeCached(file.url, entry); if (!file.sha1.isEmpty()) { @@ -145,8 +149,8 @@ void PackInstallTask::install() setStatus(tr("Copying modpack files")); for (auto iter = filesToCopy.begin(); iter != filesToCopy.end(); iter++) { - auto &from = iter.key(); - auto &to = iter.value(); + auto &to = iter.key(); + auto &from = iter.value(); FS::copy fileCopyOperation(from, to); if(!fileCopyOperation()) { qWarning() << "Failed to copy" << from << "to" << to; diff --git a/launcher/package/ubuntu/README.md b/launcher/package/ubuntu/README.md index 892abd12..ddc97ae6 100644 --- a/launcher/package/ubuntu/README.md +++ b/launcher/package/ubuntu/README.md @@ -6,9 +6,9 @@ It contains a `.desktop` file, an icon, and a simple script that does the heavy This is also the source for the files in the [RPM package](../rpm). If you rename, create or delete files here, you'll likely also have to update the RPM spec file there. # How to build this? -You need dpkg utils. Rename the `multimc` folder to `multimc_1.5-1` and then run: +You need dpkg utils. Rename the `multimc` folder to `multimc_1.6-1` and then run: ``` -fakeroot dpkg-deb --build multimc_1.5-1 +fakeroot dpkg-deb --build multimc_1.6-1 ``` Replace the version with whatever is appropriate. diff --git a/launcher/package/ubuntu/multimc/DEBIAN/control b/launcher/package/ubuntu/multimc/DEBIAN/control index 3e0f570c..be64f517 100644 --- a/launcher/package/ubuntu/multimc/DEBIAN/control +++ b/launcher/package/ubuntu/multimc/DEBIAN/control @@ -1,5 +1,5 @@ Package: multimc -Version: 1.5-1 +Version: 1.6-1 Architecture: all Maintainer: Petr Mrázek <peterix@gmail.com> Section: games 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 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/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc index 1a6ec0dc..0ae7d4d0 100644 --- a/launcher/resources/OSX/OSX.qrc +++ b/launcher/resources/OSX/OSX.qrc @@ -28,6 +28,7 @@ <file>scalable/quickmods.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> <file>scalable/status-bad.svg</file> diff --git a/launcher/resources/OSX/scalable/shaderpacks.svg b/launcher/resources/OSX/scalable/shaderpacks.svg new file mode 100644 index 00000000..cf8251ba --- /dev/null +++ b/launcher/resources/OSX/scalable/shaderpacks.svg @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + version="1.1" + id="Calque_1" + x="0px" + y="0px" + viewBox="0 0 24 24" + enable-background="new 0 0 24 24" + xml:space="preserve" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><defs + id="defs19" /> +<rect + fill="none" + width="24" + height="24" + id="rect2" /> +<path + fill-rule="evenodd" + clip-rule="evenodd" + fill="#E6E6E6" + d="M22,6c0-0.6-0.4-1-1-1H9C8.4,5,8,5.4,8,6v12c0,0.6,0.4,1,1,1h12 c0.6,0,1-0.4,1-1V6z" + id="path4" /> + +<g + id="g14"> + <path + fill-rule="evenodd" + clip-rule="evenodd" + fill="#585858" + d="M21,20H9c-1.1,0-2-0.9-2-2V6c0-1.1,0.9-2,2-2h12c1.1,0,2,0.9,2,2 v12C23,19.1,22.1,20,21,20z M22,6c0-0.6-0.4-1-1-1H9C8.4,5,8,5.4,8,6v12c0,0.6,0.4,1,1,1h12c0.6,0,1-0.4,1-1V6z" + id="path8" /> + +</g> +<path + style="fill:#f2f2f2;fill-rule:evenodd;stroke:#585858;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1" + d="M 10,17 V 9 h 8 v 8 z" + id="path1663" /><path + style="fill:#ffffff;fill-rule:evenodd;stroke:#585858;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1" + d="m 10,9 2,-2 h 8 l -2,2 z" + id="path1665" /><path + style="fill:#cccccc;fill-rule:evenodd;stroke:#585858;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1" + d="m 18,9 v 8 l 2,-2 V 7 Z" + id="path1667" /></svg> diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index 614d7f98..a3cd51f8 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -32,6 +32,7 @@ <file>scalable/reddit-alien.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshot-placeholder.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> diff --git a/launcher/resources/flat/scalable/shaderpacks.svg b/launcher/resources/flat/scalable/shaderpacks.svg new file mode 100644 index 00000000..f1460bd9 --- /dev/null +++ b/launcher/resources/flat/scalable/shaderpacks.svg @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + fill="#757575" + height="24" + viewBox="0 0 24 24" + width="24" + version="1.1" + id="svg4" + sodipodi:docname="shaderpacks.svg" + inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs8" /> + <sodipodi:namedview + id="namedview6" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="9.7227182" + inkscape:cx="16.302025" + inkscape:cy="3.1884088" + inkscape:window-width="3840" + inkscape:window-height="2129" + inkscape:window-x="1200" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg4"> + <inkscape:grid + type="xygrid" + id="grid974" /> + </sodipodi:namedview> + <path + id="path2" + d="M 5 3 C 3.9 3 3 3.9 3 5 L 3 7 L 5 5 L 7 3 L 5 3 z M 11.880859 3 L 9.8808594 5 L 12.710938 5 L 14.710938 3 L 11.880859 3 z M 19.509766 3.0800781 L 17.589844 5 L 19 5 L 19 6.4179688 L 20.929688 4.4902344 C 20.739687 3.8002344 20.199766 3.2600781 19.509766 3.0800781 z M 21 9.2890625 L 19 11.289062 L 19 14.119141 L 21 12.119141 L 21 9.2890625 z M 5 9.8808594 L 3 11.880859 L 3 14.710938 L 5 12.710938 L 5 9.8808594 z M 21 17 L 19 19 L 17 21 L 19 21 C 19.55 21 20.050156 20.780156 20.410156 20.410156 C 20.780156 20.050156 21 19.55 21 19 L 21 17 z M 5 17.589844 L 3.0800781 19.509766 C 3.1700781 19.849766 3.3498438 20.160156 3.5898438 20.410156 C 3.8398438 20.650156 4.1502344 20.829922 4.4902344 20.919922 L 6.4121094 19 L 5 19 L 5 17.589844 z M 11.289062 19 L 9.2890625 21 L 12.119141 21 L 14.119141 19 L 11.289062 19 z " /> + <path + style="fill:none;fill-rule:evenodd;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" + d="m 7,9 v 8 h 8 V 9 Z" + id="path6727" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#757575;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" + d="M 7,9 9,7 h 8 l -2,2 z" + id="path7008" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#757575;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" + d="m 17,7 v 8 l -2,2 V 9 Z" + id="path7010" + sodipodi:nodetypes="ccccc" /> +</svg> diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc index 75c88bb0..4aa3e891 100644 --- a/launcher/resources/iOS/iOS.qrc +++ b/launcher/resources/iOS/iOS.qrc @@ -28,6 +28,7 @@ <file>scalable/quickmods.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> <file>scalable/status-bad.svg</file> diff --git a/launcher/resources/iOS/scalable/shaderpacks.svg b/launcher/resources/iOS/scalable/shaderpacks.svg new file mode 100644 index 00000000..a2aa1b21 --- /dev/null +++ b/launcher/resources/iOS/scalable/shaderpacks.svg @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + version="1.1" + id="Calque_1" + x="0px" + y="0px" + viewBox="0 0 32 32" + enable-background="new 0 0 32 32" + xml:space="preserve" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><defs + id="defs10"><linearGradient + id="linearGradient3249"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop3247" /></linearGradient></defs> +<g + id="_x32__5_"> + <g + id="g4"> + <path + fill="#3366cc" + d="M 28,0 H 4 C 1.8,0 0,1.8 0,4 v 24 c 0,2.2 1.8,4 4,4 h 24 c 2.2,0 4,-1.8 4,-4 V 4 C 32,1.8 30.2,0 28,0 Z m 2,28 c 0,1.1 -0.9,2 -2,2 H 4 C 2.9,30 2,29.1 2,28 V 4 C 2,2.9 2.9,2 4,2 h 24 c 1.1,0 2,0.9 2,2 z" + id="path2" /> + </g> +</g> +<path + style="fill:none;fill-rule:evenodd;stroke:#3366cc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 7,11 v 11 l 9,5 V 16 Z" + id="path58496" /><path + style="fill:none;fill-rule:evenodd;stroke:#3366cc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;paint-order:normal;stroke-miterlimit:4;stroke-dasharray:none" + d="m 16,27 9,-5 V 11 l -9,5 z" + id="path58498" /><path + style="fill:none;fill-rule:evenodd;stroke:#3366cc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 16,6 9,5 -9,5 -9,-5 z" + id="path36178" /></svg> diff --git a/launcher/resources/multimc/128x128/shaderpacks.png b/launcher/resources/multimc/128x128/shaderpacks.png Binary files differnew file mode 100644 index 00000000..1de0e916 --- /dev/null +++ b/launcher/resources/multimc/128x128/shaderpacks.png diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc index 249e8e28..eec10ea4 100644 --- a/launcher/resources/multimc/multimc.qrc +++ b/launcher/resources/multimc/multimc.qrc @@ -197,6 +197,9 @@ <file>32x32/resourcepacks.png</file> <file>64x64/resourcepacks.png</file> + <!-- Resource packs, CC-BY-SA 3.0, Oxygen icons. --> + <file>128x128/shaderpacks.png</file> + <!-- Refresh, CC-BY-SA 3.0, Oxygen icons. --> <file>16x16/refresh.png</file> <file>22x22/refresh.png</file> diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 2a685979..2446e4c3 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -28,6 +28,7 @@ <file>scalable/quickmods.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> <file>scalable/status-bad.svg</file> diff --git a/launcher/resources/pe_blue/scalable/shaderpacks.svg b/launcher/resources/pe_blue/scalable/shaderpacks.svg new file mode 100644 index 00000000..530e1ad4 --- /dev/null +++ b/launcher/resources/pe_blue/scalable/shaderpacks.svg @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xml:space="preserve" + enable-background="new 0 0 32 32" + viewBox="0 0 32 32" + y="0px" + x="0px" + id="Calque_1" + version="1.1" + sodipodi:docname="shaderpacks.svg" + inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview + id="namedview27" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="20.625" + inkscape:cx="15.975758" + inkscape:cy="16" + inkscape:window-width="1502" + inkscape:window-height="903" + inkscape:window-x="1472" + inkscape:window-y="544" + inkscape:window-maximized="0" + inkscape:current-layer="Calque_1" /><metadata + id="metadata45"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs43" /><path + id="path2" + d="M26,32H6c-3.3,0-6-2.7-6-6V6c0-3.3,2.7-6,6-6h20c3.3,0,6,2.7,6,6 v20C32,29.3,29.3,32,26,32z" + fill="#3366CC" + clip-rule="evenodd" + fill-rule="evenodd" /><path + fill="#DAEEFF" + fill-rule="evenodd" + clip-rule="evenodd" + id="path4" + d="M28,6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6v20c0,1.1,0.9,2,2,2h20 c1.1,0,2-0.9,2-2V6z" /><g + id="g834"><path + id="polygon840" + style="clip-rule:evenodd;fill:#294eab;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -433,272.1 v 17.8 l -14,7.1 v -17.8 z" /><path + id="polygon842" + style="clip-rule:evenodd;fill:#39b54a;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -461,272.1 v 17.8 l 14,7.1 v -17.8 z" /><path + id="polygon844" + style="clip-rule:evenodd;fill:#ed4c31;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -447,265 -14,7.1 14,7.1 14,-7.1 z" /></g><g + id="g10" /><g + id="g12" /><g + id="g14" /><g + id="g16" /><g + id="g18" /><g + id="g20" /><g + id="g22" /><g + id="g24" /><g + id="g26" /><g + id="g28" /><g + id="g30" /><g + id="g32" /><g + id="g34" /><g + id="g36" /><g + id="g38" /></svg> 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 @@ <file>scalable/resourcepacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/status-bad.svg</file> <file>scalable/status-good.svg</file> <file>scalable/status-yellow.svg</file> 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xml:space="preserve" + enable-background="new 0 0 32 32" + viewBox="0 0 32 32" + y="0px" + x="0px" + id="Calque_1" + version="1.1" + sodipodi:docname="shaderpacks.svg" + inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview + id="namedview14" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="14.584077" + inkscape:cx="24.478752" + inkscape:cy="13.165043" + inkscape:window-width="2399" + inkscape:window-height="1183" + inkscape:window-x="2321" + inkscape:window-y="798" + inkscape:window-maximized="0" + inkscape:current-layer="Calque_1" /><metadata + id="metadata19"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs17"><linearGradient + id="linearGradient3249" + inkscape:swatch="solid"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop3247" /></linearGradient> + + + + + + </defs><g + id="g6"><path + id="path2" + d="M26,0H6C2.7,0,0,2.7,0,6v3h32V6C32,2.7,29.3,0,26,0z" + fill="#39B54A" /><path + id="path4" + d="M0,26c0,3.3,2.7,6,6,6h20c3.3,0,6-2.7,6-6V9H0V26z" + fill="#8C6239" /></g><path + fill="#F2F2F2" + fill-rule="evenodd" + clip-rule="evenodd" + id="path8" + d="M28,6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6v20c0,1.1,0.9,2,2,2h20 c1.1,0,2-0.9,2-2V6z" /><rect + x="6.0678372" + y="6.0678444" + fill-rule="evenodd" + clip-rule="evenodd" + fill="none" + width="19.864313" + height="19.864313" + id="rect838" + style="stroke-width:1.98049" /><path + id="polygon840" + style="clip-rule:evenodd;fill:#294eab;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -433,272.1 v 17.8 l -14,7.1 v -17.8 z" /><path + id="polygon842" + style="clip-rule:evenodd;fill:#39b54a;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -461,272.1 v 17.8 l 14,7.1 v -17.8 z" /><path + id="polygon844" + style="clip-rule:evenodd;fill:#ed4c31;fill-rule:evenodd;stroke-width:3.19043" + transform="matrix(0.62075979,0,0,0.62075979,293.47962,-158.4335)" + d="m -447,265 -14,7.1 14,7.1 14,-7.1 z" /></svg> diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index a138abc4..c631c0a5 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -28,6 +28,7 @@ <file>scalable/quickmods.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> <file>scalable/status-bad.svg</file> diff --git a/launcher/resources/pe_dark/scalable/shaderpacks.svg b/launcher/resources/pe_dark/scalable/shaderpacks.svg new file mode 100644 index 00000000..9cca756b --- /dev/null +++ b/launcher/resources/pe_dark/scalable/shaderpacks.svg @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xml:space="preserve" + enable-background="new 0 0 32 32" + viewBox="0 0 32 32" + y="0px" + x="0px" + id="Calque_1" + version="1.1" + sodipodi:docname="shaderpacks.svg" + inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview + id="namedview27" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="true" + inkscape:zoom="20.625" + inkscape:cx="0.024242424" + inkscape:cy="16" + inkscape:window-width="3840" + inkscape:window-height="2129" + inkscape:window-x="1200" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Calque_1"><inkscape:grid + type="xygrid" + id="grid22050" /></sodipodi:namedview><metadata + id="metadata45"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs43" /><rect + style="color:#000000;overflow:visible;fill:#000000;fill-opacity:1;stroke:none;stroke-linejoin:round" + id="rect22154" + width="32" + height="32" + x="0" + y="0" + rx="5" + ry="5" /><rect + style="color:#000000;overflow:visible;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-linejoin:round" + id="rect22569" + width="24" + height="24" + x="4" + y="4" + rx="2" + ry="2" /><path + id="polygon840" + style="clip-rule:evenodd;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 24.690631,10.475239 v 11.049524 l -8.690637,4.407395 V 14.882633 Z" /><path + id="polygon842" + style="clip-rule:evenodd;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 7.3093568,10.475239 v 11.049524 l 8.6906372,4.407395 V 14.882633 Z" /><path + id="polygon844" + style="clip-rule:evenodd;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 15.999994,6.0678444 -8.6906372,4.4073946 8.6906372,4.407394 8.690637,-4.407394 z" /><g + id="g10" /><g + id="g12" /><g + id="g14" /><g + id="g16" /><g + id="g18" /><g + id="g20" /><g + id="g22" /><g + id="g24" /><g + id="g26" /><g + id="g28" /><g + id="g30" /><g + id="g32" /><g + id="g34" /><g + id="g36" /><g + id="g38" /></svg> diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index f518b650..a687ed21 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -28,6 +28,7 @@ <file>scalable/quickmods.svg</file> <file>scalable/refresh.svg</file> <file>scalable/resourcepacks.svg</file> + <file>scalable/shaderpacks.svg</file> <file>scalable/screenshots.svg</file> <file>scalable/settings.svg</file> <file>scalable/status-bad.svg</file> diff --git a/launcher/resources/pe_light/scalable/shaderpacks.svg b/launcher/resources/pe_light/scalable/shaderpacks.svg new file mode 100644 index 00000000..76356ee7 --- /dev/null +++ b/launcher/resources/pe_light/scalable/shaderpacks.svg @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xml:space="preserve" + enable-background="new 0 0 32 32" + viewBox="0 0 32 32" + y="0px" + x="0px" + id="Calque_1" + version="1.1" + sodipodi:docname="shaderpacks.svg" + inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview + id="namedview27" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="true" + inkscape:zoom="20.625" + inkscape:cx="0.024242424" + inkscape:cy="16" + inkscape:window-width="3840" + inkscape:window-height="2129" + inkscape:window-x="1200" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Calque_1"><inkscape:grid + type="xygrid" + id="grid22050" /></sodipodi:namedview><metadata + id="metadata45"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs43" /><rect + style="color:#000000;overflow:visible;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-linejoin:round" + id="rect22154" + width="32" + height="32" + x="0" + y="0" + rx="5" + ry="5" /><rect + style="color:#000000;overflow:visible;fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-linejoin:round" + id="rect22569" + width="24" + height="24" + x="4" + y="4" + rx="2" + ry="2" /><path + id="polygon840" + style="clip-rule:evenodd;fill:#878787;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 24.690631,10.475239 v 11.049524 l -8.690637,4.407395 V 14.882633 Z" /><path + id="polygon842" + style="clip-rule:evenodd;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 7.3093568,10.475239 v 11.049524 l 8.6906372,4.407395 V 14.882633 Z" /><path + id="polygon844" + style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:1.98049" + d="m 15.999994,6.0678444 -8.6906372,4.4073946 8.6906372,4.407394 8.690637,-4.407394 z" /><g + id="g10" /><g + id="g12" /><g + id="g14" /><g + id="g16" /><g + id="g18" /><g + id="g20" /><g + id="g22" /><g + id="g24" /><g + id="g26" /><g + id="g28" /><g + id="g30" /><g + id="g32" /><g + id="g34" /><g + id="g36" /><g + id="g38" /></svg> 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 <QObject> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QNetworkAccessManager> -#include <QUrl> -#include <QByteArray> -#include <QHttpMultiPart> - -#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<QNetworkReply::RawHeaderPair> 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<QSslError> 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 <cassert> - -#include <QDebug> -#include <QTimer> -#include <QBuffer> -#include <QUrlQuery> - -#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>("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<QNetworkReply *>(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<QNetworkReply *>(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<QSslError> 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<QNetworkReply *>(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<QNetworkReply::RawHeaderPair> 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))); -} - -} |