diff --git a/README.md b/README.md index 88782b2..77965aa 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,6 @@ plugins! * Game Patching Support: Can patch the game without the need to boot into the official launcher. * Alternative Server Support: Can use alternative servers in case the official ones ever disappear. -**Note:** Steam-linked Square Enix accounts are not currently supported. You will have to use the official launcher or XIVLauncher.Core. - ## Get It Details on where to find stable releases of Astra can be found on its [homepage](https://xiv.zone/astra/install). diff --git a/autotests/encryptedargtest.cpp b/autotests/encryptedargtest.cpp index 7b3a933..d69d7ff 100644 --- a/autotests/encryptedargtest.cpp +++ b/autotests/encryptedargtest.cpp @@ -12,30 +12,37 @@ class EncryptedArgTest : public QObject private Q_SLOTS: void steamTicket_data() { - QTest::addColumn("ticketBytes"); + QTest::addColumn("ticketBytes"); QTest::addColumn("time"); QTest::addColumn("encryptedTicket"); + QTest::addColumn("encryptedLength"); - QTest::addRow("test 1") << QByteArrayLiteral( - "caf59103e80d600b4a9233358c131a437cedcf8802eb705223cce84278e6cb4c3655a7accd98097c06748b33d340f9de79920754616e295b88b833d9d84412ffc6a4406c60a6691ce5" - "2c27b5b1c90d36a6a810cef4c81fdc3c75aaa87353433f2f3c7232c00d1198a79bb27df6edb89c5fd0a3a11e957c40") - << static_cast(1746386404) - << QStringLiteral( - "jX6TeGNIJFgecYIQU4YLSnhkbCpTihoIBB6Dw5iw7rAWQiULVB-NhOsfJwLh7EHW5wYwU1XRJAy5dw6JCWQ6v0R5SwP_84DIVDT5gfET_" - "BoXmUr7rfXtJF62vpZ16XfwH2-P2KlaVRTaSYQ8xqTqC_fef6agOdYHvL_g-cNyjjv3xTMsekWnDCDhdG3Y1NvnPcXdAX9v0pjHUu5W5-" - "k8iZhUeTcTjYhMODBPNXz6uf7mKd1wkwAsTnDZoL89k8U1asq78hyaiWsFb4Nb39vK0n0TZfb20yFoXZh9NRO2VpgS,dSTy86oaqm2ZjKu7FnnHmFU6R_" - "lS8pk8EB6itIekPAfC37LYSBIEI1rT9cEvoXNkX6hIGnZ5sthiNPoi5nx9_HdjWYQ9R0Kar-Bgjeu77Av753T0GpVhJhYFyBkMe-" - "NAqGMEjkYFjRUwOX9pEJGEszEL3_mWEbryQ8wL4ZaYk5xu4HAXe5hRwk-JUv__BW8IpiR_OsphQUgeKtRmXUPw1eIU2NYdsd3AJLAP3tiiENaplJ_y8X_" - "OmC8tzvKCCdXapsas3-Won2R_ryQVJlB9j1tAARpNanIEwhOf9CHmbsYM,-8tTNfrKABIfOSlCdr2ajhLqF1i4hRiM-jSzISXAEmc-Nj75Rrg*"); + QTest::addRow("real ticket") + << QStringLiteral( + "140000009efb2c79d200f07599f633050100100195c517681800000001000000020000002c9ea991afec1a49f7e72d000b000000b8000000380000000400000099f63305010" + "010012a990000c47323496501a8c000000000807a1268002a2e680100908400000100c5000400000000004e408e518c259b8b329b5fcfdb00903fadad36d7e088813dc9b174" + "b06e08b69f8f46d083cf4118d1eb4062e009147906d9c80759af3eb221f7fbb8e28d402e11ba80e3cf4a101487f87ccce9688daf99dd412e6bcaab6e58f70030ff99323e4c8" + "1824659f7aa89188fadc6402bcb540843e1578cd112d4536fd65c4bd926f754") + << static_cast(1746389891) + << QStringLiteral( + "Tjr8Lv1O0HjJ7U4dOfkA9BdLAnEaCl_TU0GnYGGLTBM06TV9Ggf-fYb7WMqD-Xv758Q1zzSPTeaJctl8au-" + "imM4ACRgl0Y4LqJpLFfgBhkumd4dne2P9oM6qLzMnHfspPq8AFQFHXaiSicu2gSaCwpk36ZK-WX17DaTOkYFncIKl_rSZAkb8OzTpNX0aB_590hUpAf74-" + "TU368A1fgXLw2aunwn0wBNvz0ywFEiAjmD8PfgUzA6IrvkP1eoKoY4A_NNBXnirca7CjWxOoguXRGaHjzq9vrDm8ABTk2o0u29R,Nqmz_4LN1Fj9cNhtyhHTXuV6huLxmsflb_" + "6DR5B8dwk8IMYup0z5AXHhLww0BmZkDKKCWjVehxWvoHkz8FNViV9Oduwv7ZGyHUYs47HUpOIr1Wirp6LEvsxBcDBf-T_XOK945j-z_" + "MtxXiNKqtAuaL8iw7OOIpVnXqIa77yGuOFFW-u2wv1cK1M3s_OqmgEdj0JZfoYbjT6lIEVsSXKMYwwf9zkAjx23K-gqrM8c8nStv4EYT7ZU6o_" + "I0KZ6OJVnCFElYLamz82NIRiPdzyuJcPoslNCXpQV_vWlyGJ0OIoR,2MrkkwMnTNx7HR4FJ6ACh0cQZmdBEB2pM4eQSqpJEC367JtCMzM*") + << 652; } void steamTicket() { - QFETCH(QByteArray, ticketBytes); + QFETCH(QString, ticketBytes); QFETCH(uint32_t, time); QFETCH(QString, encryptedTicket); + QFETCH(int, encryptedLength); - QCOMPARE(encryptSteamTicket(ticketBytes, time), encryptedTicket); + auto pair = std::pair{encryptedTicket, encryptedLength}; + QCOMPARE(encryptSteamTicket(ticketBytes, time), pair); } }; diff --git a/launcher/include/encryptedarg.h b/launcher/include/encryptedarg.h index 2aa7a1d..bf41124 100644 --- a/launcher/include/encryptedarg.h +++ b/launcher/include/encryptedarg.h @@ -6,4 +6,4 @@ #include QString encryptGameArg(const QString &arg); -QString encryptSteamTicket(const QByteArray &ticket, uint32_t time); +std::pair encryptSteamTicket(QString ticket, uint32_t time); diff --git a/launcher/include/steamapi.h b/launcher/include/steamapi.h index 34b14c1..5bf3634 100644 --- a/launcher/include/steamapi.h +++ b/launcher/include/steamapi.h @@ -16,8 +16,8 @@ public: QCoro::Task<> initialize(); QCoro::Task<> shutdown(); - QCoro::Task getTicket(); + QCoro::Task> getTicket(); private: QNetworkAccessManager m_qnam; -}; \ No newline at end of file +}; diff --git a/launcher/src/encryptedarg.cpp b/launcher/src/encryptedarg.cpp index 80440e8..f3411b8 100644 --- a/launcher/src/encryptedarg.cpp +++ b/launcher/src/encryptedarg.cpp @@ -101,13 +101,13 @@ QStringList intoChunks(const QString &str, const int maxChunkSize) return chunks; } -QString encryptSteamTicket(const QByteArray &ticket, uint32_t time) +std::pair encryptSteamTicket(QString ticket, uint32_t time) { // Round the time down time -= 5; time -= time % 60; - auto ticketString = QString::fromLatin1(ticket.toHex()).remove(QLatin1Char('-')).toLower(); + auto ticketString = ticket.remove(QLatin1Char('-')).toLower(); auto rawTicketBytes = ticketString.toLatin1(); rawTicketBytes.append('\0'); @@ -160,5 +160,8 @@ QString encryptSteamTicket(const QByteArray &ticket, uint32_t time) encoded.replace('/', '_'); encoded.replace('=', '*'); - return intoChunks(QString::fromLatin1(encoded), SPLIT_SIZE).join(QLatin1Char(',')); + const auto parts = intoChunks(QString::fromLatin1(encoded), SPLIT_SIZE); + const auto finalString = parts.join(QLatin1Char(',')); + + return {finalString, finalString.length() - (parts.length() - 1)}; } diff --git a/launcher/src/squareenixlogin.cpp b/launcher/src/squareenixlogin.cpp index e972576..65715ae 100644 --- a/launcher/src/squareenixlogin.cpp +++ b/launcher/src/squareenixlogin.cpp @@ -232,12 +232,13 @@ QCoro::Task> SquareEnixLogin::getStor if (m_info->profile->account()->config()->license() == Account::GameLicense::WindowsSteam) { query.addQueryItem(QStringLiteral("issteam"), QString::number(1)); + // initialize the steam api co_await m_launcher.steamApi()->initialize(); - auto ticket = co_await m_launcher.steamApi()->getTicket(); - + // grab an auth ticket + auto [ticket, ticketSize] = co_await m_launcher.steamApi()->getTicket(); query.addQueryItem(QStringLiteral("session_ticket"), ticket); - query.addQueryItem(QStringLiteral("ticket_size"), QString::number(ticket.length())); + query.addQueryItem(QStringLiteral("ticket_size"), QString::number(ticketSize)); } QUrl url; diff --git a/launcher/src/steamapi.cpp b/launcher/src/steamapi.cpp index de5f978..3fae9e8 100644 --- a/launcher/src/steamapi.cpp +++ b/launcher/src/steamapi.cpp @@ -34,7 +34,7 @@ QCoro::Task<> SteamAPI::shutdown() Q_UNUSED(co_await m_qnam.post(QNetworkRequest(url), QByteArray{})) } -QCoro::Task SteamAPI::getTicket() +QCoro::Task> SteamAPI::getTicket() { QUrl url; url.setScheme(QStringLiteral("http")); @@ -45,5 +45,7 @@ QCoro::Task SteamAPI::getTicket() const auto reply = co_await m_qnam.get(QNetworkRequest(url)); const auto ticketBytes = reply->readAll(); - co_return encryptSteamTicket(ticketBytes, 5); // TOOD: get time + const QJsonDocument document = QJsonDocument::fromJson(ticketBytes); + + co_return encryptSteamTicket(document[QStringLiteral("ticket")].toString(), document[QStringLiteral("ticket")].toInt()); } diff --git a/launcher/ui/Setup/AddSquareEnix.qml b/launcher/ui/Setup/AddSquareEnix.qml index 0ddbd5a..007d783 100644 --- a/launcher/ui/Setup/AddSquareEnix.qml +++ b/launcher/ui/Setup/AddSquareEnix.qml @@ -47,13 +47,6 @@ FormCard.FormCardPage { description: i18n("If the account holds multiple licenses, choose the preferred one.") model: ["Windows", "Steam", "macOS"] text: i18n("License") - - onCurrentIndexChanged: { - if (currentIndex === 1) { - currentIndex = 0; - errorDialog.open(); - } - } } FormCard.FormDelegateSeparator { above: licenseField @@ -87,12 +80,4 @@ FormCard.FormCardPage { } } } - Kirigami.PromptDialog { - id: errorDialog - - showCloseButton: false - standardButtons: Kirigami.Dialog.Ok - title: i18n("Steam Warning") - subtitle: i18n("Steam linked Square Enix accounts are not currently supported. You will have to use another launcher that supports these, such as the official launcher or XIVLauncher.Core.") - } -} \ No newline at end of file +}