From 0775a463e8adb47864c5dbf22685f1769ad14c9b Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 22 Aug 2024 20:42:35 -0400 Subject: [PATCH] Port to Physis' patchlist parsing, remove our own Also start checking the available space before downloading patches to avoid really bad situations. This will be expanded in the future. --- autotests/CMakeLists.txt | 6 -- autotests/patchlisttest.cpp | 94 -------------------------------- external/libphysis | 2 +- launcher/CMakeLists.txt | 2 - launcher/include/patcher.h | 7 +-- launcher/include/patchlist.h | 29 ---------- launcher/include/utility.h | 1 + launcher/src/patcher.cpp | 52 ++++++++++++------ launcher/src/patchlist.cpp | 47 ---------------- launcher/src/squareenixlogin.cpp | 12 +++- launcher/src/utility.cpp | 6 ++ 11 files changed, 54 insertions(+), 204 deletions(-) delete mode 100644 autotests/patchlisttest.cpp delete mode 100644 launcher/include/patchlist.h delete mode 100644 launcher/src/patchlist.cpp diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index cfbd4e9..376173c 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -7,12 +7,6 @@ ecm_add_test(accountmanagertest.cpp NAME_PREFIX "astra-" ) -ecm_add_test(patchlisttest.cpp - TEST_NAME patchlisttest - LINK_LIBRARIES astra_static Qt::Test - NAME_PREFIX "astra-" -) - ecm_add_test(processwatchertest.cpp TEST_NAME processwatchertest LINK_LIBRARIES astra_static Qt::Test diff --git a/autotests/patchlisttest.cpp b/autotests/patchlisttest.cpp deleted file mode 100644 index 7c2e7fb..0000000 --- a/autotests/patchlisttest.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Joshua Goins -// SPDX-License-Identifier: GPL-3.0-or-later - -#include - -#include "patchlist.h" - -class PatchListTest : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void testBootPatchList() - { - const QString testCase{ - QStringLiteral("--477D80B1_38BC_41d4_8B48_5273ADB89CAC\r\nContent-Type: application/octet-stream\r\nContent-Location: " - "ffxivpatch/2b5cbc63/metainfo/D2023.04.28.0000.0001.http\r\nX-Patch-Length: " - "22221335\r\n\r\n22221335\t69674819\t19\t18\t2023.09.14.0000.0001\thttp://patch-dl.ffxiv.com/boot/2b5cbc63/" - "D2023.09.14.0000.0001.patch\r\n--477D80B1_38BC_41d4_8B48_5273ADB89CAC--\r\n")}; - - const PatchList patchList{testCase}; - - QCOMPARE(patchList.patches().size(), 1); - QCOMPARE(patchList.patches()[0].version, QStringLiteral("2023.09.14.0000.0001")); - QCOMPARE(patchList.patches()[0].url, QStringLiteral("http://patch-dl.ffxiv.com/boot/2b5cbc63/D2023.09.14.0000.0001.patch")); - } - - void testGamePatchList() - { - const QString testCase{QStringLiteral( - "--477D80B1_38BC_41d4_8B48_5273ADB89CAC\r\nContent-Type: application/octet-stream\r\nContent-Location: " - "ffxivpatch/4e9a232b/metainfo/2023.07.26.0000.0000.http\r\nX-Patch-Length: " - "1664916486\r\n\r\n1479062470\t44145529682\t71\t11\t2023.09.15.0000.0000\tsha1\t50000000\t1c66becde2a8cf26a99d0fc7c06f15f8bab2d87c," - "950725418366c965d824228bf20f0496f81e0b9a,cabef48f7bf00fbf18b72843bdae2f61582ad264,53608de567b52f5fdb43fdb8b623156317e26704," - "f0bc06cabf9ff6490f36114b25f62619d594dbe8,3c5e4b962cd8445bd9ee29011ecdb331d108abd8,88e1a2a322f09de3dc28173d4130a2829950d4e0," - "1040667917dc99b9215dfccff0e458c2e8a724a8,149c7e20e9e3e376377a130e0526b35fd7f43df2,1bb4e33807355cdf46af93ce828b6e145a9a8795," - "a79daff43db488f087da8e22bb4c21fd3a390f3c,6b04fadb656d467fb8318eba1c7f5ee8f030d967,a6641e1c894db961a49b70fda2b0d6d87be487a7," - "edf419de49f42ef19bd6814f8184b35a25e9e977,c1525c4df6001b66b575e2891db0284dc3a16566,01b7628095b07fa3c9c1aed2d66d32d118020321," - "991b137ea0ebb11bd668f82149bc2392a4cbcf52,ad3f74d4fca143a6cf507fc859544a4bcd501d85,936a0f1711e273519cae6b2da0d8b435fe6aa020," - "023f19d8d8b3ecaaf865e3170e8243dd437a384c,2d9e934de152956961a849e81912ca8d848265ca,8e32f9aa76c95c60a9dbe0967aee5792b812d5ec," - "dee052b9aa1cc8863efd61afc63ac3c2d56f9acc,fa81225aea53fa13a9bae1e8e02dea07de6d7052,59b24693b1b62ea1660bc6f96a61f7d41b3f7878," - "349b691db1853f6c0120a8e66093c763ba6e3671,4561eb6f954d80cdb1ece3cc4d58cbd864bf2b50,de94175c4db39a11d5334aefc7a99434eea8e4f9," - "55dd7215f24441d6e47d1f9b32cebdb041f2157f,2ca09db645cfeefa41a04251dfcb13587418347a\thttp://patch-dl.ffxiv.com/game/4e9a232b/" - "D2023.09.15.0000.0000.patch\r\n61259063\t44145955874\t71\t11\t2023.09.21.0000.0001\tsha1\t50000000\t88c9bbfe2af4eea7b56384baeeafd59afb47ddeb," - "095c26e87b4d25505845515c389dd22dd429ea7e\thttp://patch-dl.ffxiv.com/game/4e9a232b/" - "D2023.09.21.0000.0001.patch\r\n63776300\t44146911186\t71\t11\t2023.09.23.0000.0001\tsha1\t50000000\tc8fc6910be12d10b39e4e6ae980d4c219cfe56a1," - "5c0199b7147a47f620a2b50654a87c9b0cbcf43b\thttp://patch-dl.ffxiv.com/game/4e9a232b/" - "D2023.09.23.0000.0001.patch\r\n32384649\t44146977234\t71\t11\t2023.09.26.0000." - "0000\tsha1\t50000000\t519a5e46edb67ba6edb9871df5eb3991276da254\thttp://patch-dl.ffxiv.com/game/4e9a232b/" - "D2023.09.26.0000.0000.patch\r\n28434004\t44147154898\t71\t11\t2023.09.28.0000." - "0000\tsha1\t50000000\ta08e8a071b615b0babc45a09979ab6bc70affe14\thttp://patch-dl.ffxiv.com/game/4e9a232b/" - "D2023.09.28.0000.0000.patch\r\n82378953\t5854598228\t30\t4\t2023.07.26.0000.0001\tsha1\t50000000\t07d9fecb3975028fdf81166aa5a4cca48bc5a4b0," - "c10677985f809df93a739ed7b244d90d37456353\thttp://patch-dl.ffxiv.com/game/ex1/6b936f08/" - "D2023.07.26.0000.0001.patch\r\n29384945\t5855426508\t30\t4\t2023.09.23.0000.0001\tsha1\t50000000\tcf4970957e846e6cacfdad521252de18afc7e29b\thttp:/" - "/patch-dl.ffxiv.com/game/ex1/6b936f08/" - "D2023.09.23.0000.0001.patch\r\n136864\t5855426508\t30\t4\t2023.09.26.0000.0000\tsha1\t50000000\t3ca5e0160e1cedb7a2801048408b247095f432ea\thttp://" - "patch-dl.ffxiv.com/game/ex1/6b936f08/" - "D2023.09.26.0000.0000.patch\r\n126288\t5855426508\t30\t4\t2023.09.28.0000.0000\tsha1\t50000000\t88d201defb32366004c88b236d03278f95d9b442\thttp://" - "patch-dl.ffxiv.com/game/ex1/6b936f08/" - "D2023.09.28.0000.0000.patch\r\n49352444\t7620831756\t24\t4\t2023.09.23.0000.0001\tsha1\t50000000\t2a05a452281d119241f222f4eae43266a22560fe\thttp:/" - "/patch-dl.ffxiv.com/game/ex2/f29a3eb2/" - "D2023.09.23.0000.0001.patch\r\n301600\t7620831756\t24\t4\t2023.09.26.0000.0000\tsha1\t50000000\t215de572fe51bca45f83e19d719f52220818bc39\thttp://" - "patch-dl.ffxiv.com/game/ex2/f29a3eb2/" - "D2023.09.26.0000.0000.patch\r\n385096\t7620831756\t24\t4\t2023.09.28.0000.0000\tsha1\t50000000\t427c3fd61f2ca79698ecd6dc34e3457f6d8c01cd\thttp://" - "patch-dl.ffxiv.com/game/ex2/f29a3eb2/" - "D2023.09.28.0000.0000.patch\r\n60799419\t9737248724\t26\t4\t2023.09.23.0000.0001\tsha1\t50000000\tab064df7aec0526e8306a78e51adbbba8b129c3f," - "4e1bb58a987b3157c16f59821bc67b1464a301e5\thttp://patch-dl.ffxiv.com/game/ex3/859d0e24/" - "D2023.09.23.0000.0001.patch\r\n555712\t9737248724\t26\t4\t2023.09.26.0000.0000\tsha1\t50000000\tdb6b1f34b0b58ca0d0621ff6cebcc63e7eb692c5\thttp://" - "patch-dl.ffxiv.com/game/ex3/859d0e24/" - "D2023.09.26.0000.0000.patch\r\n579560\t9737248724\t26\t4\t2023.09.28.0000.0000\tsha1\t50000000\t67b5d62ee8202fe045c763deea38c136c5324195\thttp://" - "patch-dl.ffxiv.com/game/ex3/859d0e24/" - "D2023.09.28.0000.0000.patch\r\n867821466\t12469514712\t40\t4\t2023.09.15.0000.0001\tsha1\t50000000\t08f6164685b4363d719d09a8d0ef0910b48ec4a1," - "05819ea5182885b59f0dfb981ecab159f46d7343,6ab6106ce4153cac5edb26ad0aabc6ba718ee500,3c552f54cc3c101d9f1786156c1cbd9880a7c02f," - "e0d425f6032da1ceb60ff9ca14a10e5e89f23218,245402087bf6d535cb08bbc189647e8f56301722,a3a0630bb4ddd36b532be0e0a8982dbce1bb9053," - "eca8a1394db1e84b9ec11a99bd970e6335326da5,40546e6d37cc5ea21d26c2e00a11f46a13d99a77,f41f312ad72ee65dc97645c8f7426c35970187ca," - "e5a9966528ecab5a51059de3d5cd83a921c73a1c,c03855127d135d22c65e34e615eddbe6f38769e9,befab30a77c14743f53b20910b564bb6a97dfe86," - "dcce8ea707f03606b583d51d947a4cf99b52635e,c4a33a8c51a047706b65887bed804ec6c2c29016,a17bc8bd8709c2a0c5725c134101132d3536e67d," - "d2b277de55a65697d80cfe8ee46199a8d7482c30,6b97cc2862c6f8f5d279be5f28cc13ed011763e5\thttp://patch-dl.ffxiv.com/game/ex4/1bf99b87/" - "D2023.09.15.0000.0001.patch\r\n17717567\t12471821656\t40\t4\t2023.09.23.0000.0001\tsha1\t50000000\tda144d5c1c173ef1d98e4e7b558414ae53bcd392\thttp:" - "//patch-dl.ffxiv.com/game/ex4/1bf99b87/" - "D2023.09.23.0000.0001.patch\r\n3117253\t12471859944\t40\t4\t2023.09.26.0000.0000\tsha1\t50000000\t7acdab61e99d69ffa53e9136f65a1a1d3b33732b\thttp:/" - "/patch-dl.ffxiv.com/game/ex4/1bf99b87/" - "D2023.09.26.0000.0000.patch\r\n4676853\t12471859944\t40\t4\t2023.09.28.0000.0000\tsha1\t50000000\tce26ccb2115af612ccd4c42c1a27ef2ec925c81e\thttp:/" - "/patch-dl.ffxiv.com/game/ex4/1bf99b87/D2023.09.28.0000.0000.patch\r\n--477D80B1_38BC_41d4_8B48_5273ADB89CAC--\r\n")}; - - const PatchList patchList{testCase}; - QCOMPARE(patchList.patches().size(), 19); - QCOMPARE(patchList.patches()[5].version, QStringLiteral("2023.07.26.0000.0001")); - QCOMPARE(patchList.patches()[5].url, QStringLiteral("http://patch-dl.ffxiv.com/game/ex1/6b936f08/D2023.07.26.0000.0001.patch")); - } -}; - -QTEST_MAIN(PatchListTest) -#include "patchlisttest.moc" diff --git a/external/libphysis b/external/libphysis index 4dbc691..1862f3a 160000 --- a/external/libphysis +++ b/external/libphysis @@ -1 +1 @@ -Subproject commit 4dbc6917fb1b9f73ecd1ec98a8b17c13bf180273 +Subproject commit 1862f3a81f93178f55bda4ee7f88f3476f7f0062 diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c6780d1..3a8b490 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -33,7 +33,6 @@ ecm_qt_declare_logging_category(astra_static target_sources(astra_static PRIVATE include/account.h - include/patchlist.h include/processwatcher.h include/profilemanager.h include/profile.h @@ -67,7 +66,6 @@ target_sources(astra_static PRIVATE src/launchercore.cpp src/launchersettings.cpp src/account.cpp - src/patchlist.cpp src/processwatcher.cpp src/profilemanager.cpp src/profile.cpp diff --git a/launcher/include/patcher.h b/launcher/include/patcher.h index e24a8b0..c3bf046 100644 --- a/launcher/include/patcher.h +++ b/launcher/include/patcher.h @@ -3,16 +3,14 @@ #pragma once -#include #include #include +#include #include #include #include -#include "patchlist.h" - class LauncherCore; // General-purpose patcher routine. It opens a nice dialog box, handles downloading @@ -26,7 +24,7 @@ public: Patcher(LauncherCore &launcher, const QString &baseDirectory, BootData &bootData, QObject *parent = nullptr); ~Patcher() override; - QCoro::Task patch(const PatchList &patchList); + QCoro::Task patch(const physis_PatchList &patchList); private: void setupDirectories(); @@ -65,6 +63,7 @@ private: QString m_baseDirectory; BootData *m_bootData = nullptr; GameData *m_gameData = nullptr; + QStorageInfo m_patchesDirStorageInfo; int m_remainingPatches = -1; diff --git a/launcher/include/patchlist.h b/launcher/include/patchlist.h deleted file mode 100644 index d8f1aec..0000000 --- a/launcher/include/patchlist.h +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Joshua Goins -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include -#include - -class Patch -{ -public: - QString name, url, repository, version; - QList hashes; - long hashBlockSize = 0; - long length = 0; -}; - -class PatchList -{ -public: - explicit PatchList(const QString &patchList); - - [[nodiscard]] QList patches() const; - - [[nodiscard]] bool isEmpty() const; - -private: - QList m_patches; -}; \ No newline at end of file diff --git a/launcher/include/utility.h b/launcher/include/utility.h index 554fc6e..3aec33d 100644 --- a/launcher/include/utility.h +++ b/launcher/include/utility.h @@ -15,4 +15,5 @@ void setSSL(QNetworkRequest &request); QString readVersion(const QString &path); void writeVersion(const QString &path, const QString &version); bool isSteamDeck(); +QString repositoryFromPatchUrl(const QString &url); } \ No newline at end of file diff --git a/launcher/src/patcher.cpp b/launcher/src/patcher.cpp index 6f0a811..3cde240 100644 --- a/launcher/src/patcher.cpp +++ b/launcher/src/patcher.cpp @@ -3,6 +3,7 @@ #include "patcher.h" +#include #include #include #include @@ -13,7 +14,6 @@ #include "astra_patcher_log.h" #include "launchercore.h" -#include "patchlist.h" #include "utility.h" using namespace Qt::StringLiterals; @@ -49,50 +49,65 @@ Patcher::~Patcher() m_launcher.m_isPatching = false; } -QCoro::Task Patcher::patch(const PatchList &patchList) +QCoro::Task Patcher::patch(const physis_PatchList &patchList) { - if (patchList.isEmpty()) { + if (patchList.num_entries == 0) { + co_return false; + } + + const qint64 neededSpace = patchList.patch_length - m_patchesDirStorageInfo.bytesAvailable(); + if (neededSpace > 0) { + KFormat format; + QString neededSpaceStr = format.formatByteSize(neededSpace); + Q_EMIT m_launcher.miscError(i18n("There is not enough space available on disk to update the game. You need %1 of free space.", neededSpaceStr)); co_return false; } Q_EMIT m_launcher.stageIndeterminate(); Q_EMIT m_launcher.stageChanged(i18n("Updating %1", getBaseString())); - m_remainingPatches = static_cast(patchList.patches().size()); + m_remainingPatches = patchList.num_entries; m_patchQueue.resize(m_remainingPatches); QFutureSynchronizer synchronizer; int patchIndex = 0; - for (auto &patch : patchList.patches()) { + for (int i = 0; i < patchList.num_entries; i++) { + const auto &patch = patchList.entries[i]; + const int ourIndex = patchIndex++; - const QString filename = QStringLiteral("%1.patch").arg(patch.name); - const QString tempFilename = QStringLiteral("%1.patch~").arg(patch.name); // tilde afterwards to hide it easily + const QString filename = QStringLiteral("%1.patch").arg(QLatin1String(patch.version)); + const QString tempFilename = QStringLiteral("%1.patch~").arg(QLatin1String(patch.version)); // tilde afterwards to hide it easily - const QDir repositoryDir = m_patchesDir.absoluteFilePath(patch.repository); + const QString repository = Utility::repositoryFromPatchUrl(QLatin1String(patch.url)); + const QDir repositoryDir = m_patchesDir.absoluteFilePath(repository); Utility::createPathIfNeeded(repositoryDir); const QString patchPath = repositoryDir.absoluteFilePath(filename); const QString tempPatchPath = repositoryDir.absoluteFilePath(tempFilename); - const QueuedPatch queuedPatch{.name = patch.name, - .repository = patch.repository, - .version = patch.version, + QStringList convertedHashes; + for (uint64_t i = 0; i < patch.hash_count; i++) { + convertedHashes.push_back(QLatin1String(patch.hashes[i])); + } + + const QueuedPatch queuedPatch{.name = QLatin1String(patch.version), + .repository = repository, + .version = QLatin1String(patch.version), .path = patchPath, - .hashes = patch.hashes, - .hashBlockSize = patch.hashBlockSize, + .hashes = convertedHashes, + .hashBlockSize = patch.hash_block_size, .length = patch.length, .isBoot = isBoot()}; qDebug(ASTRA_PATCHER) << "Adding a queued patch:"; - qDebug(ASTRA_PATCHER) << "- Name:" << patch.name; - qDebug(ASTRA_PATCHER) << "- Repository or is boot:" << (isBoot() ? QStringLiteral("boot") : patch.repository); + qDebug(ASTRA_PATCHER) << "- Repository or is boot:" << (isBoot() ? QStringLiteral("boot") : repository); qDebug(ASTRA_PATCHER) << "- Version:" << patch.version; qDebug(ASTRA_PATCHER) << "- Downloaded Path:" << patchPath; qDebug(ASTRA_PATCHER) << "- Hashes:" << patch.hashes; - qDebug(ASTRA_PATCHER) << "- Hash Block Size:" << patch.hashBlockSize; + qDebug(ASTRA_PATCHER) << "- Hash Block Size:" << patch.hash_block_size; qDebug(ASTRA_PATCHER) << "- Length:" << patch.length; m_patchQueue[ourIndex] = queuedPatch; @@ -103,7 +118,7 @@ QCoro::Task Patcher::patch(const PatchList &patchList) QFile::remove(tempPatchPath); } - const auto patchRequest = QNetworkRequest(QUrl(patch.url)); + const auto patchRequest = QNetworkRequest(QUrl(QLatin1String(patch.url))); Utility::printRequest(QStringLiteral("GET"), patchRequest); auto patchReply = m_launcher.mgr()->get(patchRequest); @@ -135,7 +150,7 @@ QCoro::Task Patcher::patch(const PatchList &patchList) } else { m_patchQueue[ourIndex].downloaded = true; m_finishedPatches++; - qDebug(ASTRA_PATCHER) << "Found existing patch: " << patch.name; + qDebug(ASTRA_PATCHER) << "Found existing patch: " << patch.version; } } @@ -243,6 +258,7 @@ void Patcher::setupDirectories() dataDir.setPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); m_patchesDir.setPath(dataDir.absoluteFilePath(QStringLiteral("patch"))); + m_patchesDirStorageInfo = QStorageInfo(m_patchesDir); } QString Patcher::getBaseString() const diff --git a/launcher/src/patchlist.cpp b/launcher/src/patchlist.cpp deleted file mode 100644 index 8bba1be..0000000 --- a/launcher/src/patchlist.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Joshua Goins -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "patchlist.h" -#include "astra_patcher_log.h" - -using namespace Qt::StringLiterals; - -PatchList::PatchList(const QString &patchList) -{ - const QStringList parts = patchList.split(QStringLiteral("\r\n")); - - for (int i = 5; i < parts.size() - 2; i++) { - const QStringList patchParts = parts[i].split('\t'_L1); - - const int length = patchParts[0].toInt(); - - const QString &version = patchParts[4]; - const long hashBlockSize = patchParts.size() == 9 ? patchParts[6].toLong() : 0; - - const QString &name = version; - const QStringList hashes = patchParts.size() == 9 ? (patchParts[7].split(','_L1)) : QStringList(); - const QString &url = patchParts[patchParts.size() == 9 ? 8 : 5]; - - auto url_parts = url.split('/'_L1); - const QString repository = url_parts[url_parts.size() - 3]; - - m_patches.push_back( - {.name = name, .url = url, .repository = repository, .version = version, .hashes = hashes, .hashBlockSize = hashBlockSize, .length = length}); - } - - Q_ASSERT_X(m_patches.isEmpty() ? patchList.isEmpty() : true, - "PatchList", - "Patch parsing failed, we were given an non-empty patchlist body but nothing were parsed."); - - qDebug(ASTRA_PATCHER) << "Finished parsing patch list. # of patches:" << m_patches.size(); -} - -QList PatchList::patches() const -{ - return m_patches; -} - -bool PatchList::isEmpty() const -{ - return m_patches.isEmpty(); -} diff --git a/launcher/src/squareenixlogin.cpp b/launcher/src/squareenixlogin.cpp index a2705d0..7e74ad9 100644 --- a/launcher/src/squareenixlogin.cpp +++ b/launcher/src/squareenixlogin.cpp @@ -177,14 +177,19 @@ QCoro::Task SquareEnixLogin::checkBootUpdates() if (reply->error() == QNetworkReply::NoError) { const QString patchList = QString::fromUtf8(reply->readAll()); if (!patchList.isEmpty()) { + qDebug(ASTRA_LOG) << "Boot patch list:" << patchList; + m_patcher = new Patcher(m_launcher, m_info->profile->gamePath() + QStringLiteral("/boot"), *m_info->profile->bootData(), this); - const bool hasPatched = co_await m_patcher->patch(PatchList(patchList)); + const std::string patchListStd = patchList.toStdString(); + const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Boot, patchListStd.c_str())); if (hasPatched) { // update game version information m_info->profile->readGameVersion(); + } else { + co_return false; } - m_patcher->deleteLater(); m_lastRunHasPatched = true; + m_patcher->deleteLater(); } } else { qWarning(ASTRA_LOG) << "Unknown error when verifying boot files:" << reply->errorString(); @@ -376,7 +381,8 @@ QCoro::Task SquareEnixLogin::registerSession() if (!body.isEmpty()) { m_patcher = new Patcher(m_launcher, m_info->profile->gamePath() + QStringLiteral("/game"), *m_info->profile->gameData(), this); - const bool hasPatched = co_await m_patcher->patch(PatchList(body)); + std::string bodyStd = body.toStdString(); + const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Game, bodyStd.c_str())); if (hasPatched) { // re-read game version if it has updated m_info->profile->readGameVersion(); diff --git a/launcher/src/utility.cpp b/launcher/src/utility.cpp index 025be11..f10c8b8 100644 --- a/launcher/src/utility.cpp +++ b/launcher/src/utility.cpp @@ -54,3 +54,9 @@ bool Utility::isSteamDeck() { return qEnvironmentVariable("SteamDeck") == QStringLiteral("1"); } + +QString Utility::repositoryFromPatchUrl(const QString &url) +{ + auto url_parts = url.split('/'_L1); + return url_parts[url_parts.size() - 3]; +}