From 17ad1e64f824fba6d8f153191effdb2af7d387c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 27 Feb 2016 19:58:40 +0100 Subject: NOISSUE move files into paths that make more sense --- application/InstancePageProvider.h | 4 +- application/LaunchInteraction.cpp | 4 +- application/MainWindow.cpp | 4 +- application/MainWindow.h | 2 +- application/MultiMC.cpp | 12 +- application/dialogs/AccountSelectDialog.h | 2 +- application/dialogs/LoginDialog.cpp | 2 +- application/dialogs/LoginDialog.h | 2 +- application/pages/LegacyJarModPage.cpp | 2 +- application/pages/LegacyUpgradePage.cpp | 2 +- application/pages/LegacyUpgradePage.h | 2 +- application/pages/ModFolderPage.h | 2 +- application/pages/VersionPage.cpp | 14 +- application/pages/VersionPage.h | 2 +- application/pages/WorldListPage.h | 2 +- application/pages/global/AccountListPage.cpp | 2 +- application/pages/global/AccountListPage.h | 2 +- logic/BaseInstaller.cpp | 2 +- logic/BaseInstance.h | 2 +- logic/CMakeLists.txt | 102 ++-- logic/InstanceList.cpp | 6 +- logic/auth/AuthSession.cpp | 30 -- logic/auth/AuthSession.h | 51 -- logic/auth/MojangAccount.cpp | 278 ---------- logic/auth/MojangAccount.h | 173 ------ logic/auth/MojangAccountList.cpp | 427 --------------- logic/auth/MojangAccountList.h | 201 ------- logic/auth/YggdrasilTask.cpp | 254 --------- logic/auth/YggdrasilTask.h | 150 ------ logic/auth/flows/AuthenticateTask.cpp | 203 ------- logic/auth/flows/AuthenticateTask.h | 46 -- logic/auth/flows/RefreshTask.cpp | 145 ----- logic/auth/flows/RefreshTask.h | 44 -- logic/auth/flows/ValidateTask.cpp | 62 --- logic/auth/flows/ValidateTask.h | 47 -- logic/forge/ForgeInstaller.cpp | 441 --------------- logic/forge/ForgeInstaller.h | 52 -- logic/forge/ForgeMirror.h | 10 - logic/forge/ForgeMirrors.cpp | 118 ---- logic/forge/ForgeMirrors.h | 58 -- logic/forge/ForgeVersion.cpp | 55 -- logic/forge/ForgeVersion.h | 42 -- logic/forge/ForgeVersionList.cpp | 449 ---------------- logic/forge/ForgeVersionList.h | 89 --- logic/forge/ForgeXzDownload.cpp | 389 -------------- logic/forge/ForgeXzDownload.h | 66 --- logic/forge/LegacyForge.cpp | 56 -- logic/forge/LegacyForge.h | 25 - logic/ftb/FTBPlugin.cpp | 395 -------------- logic/ftb/FTBPlugin.h | 13 - logic/ftb/FTBProfileStrategy.cpp | 127 ----- logic/ftb/FTBProfileStrategy.h | 21 - logic/ftb/FTBVersion.h | 32 -- logic/ftb/LegacyFTBInstance.cpp | 27 - logic/ftb/LegacyFTBInstance.h | 13 - logic/ftb/OneSixFTBInstance.cpp | 138 ----- logic/ftb/OneSixFTBInstance.h | 27 - logic/launch/steps/LaunchMinecraft.cpp | 2 +- logic/liteloader/LiteLoaderInstaller.cpp | 141 ----- logic/liteloader/LiteLoaderInstaller.h | 39 -- logic/liteloader/LiteLoaderVersionList.cpp | 275 ---------- logic/liteloader/LiteLoaderVersionList.h | 119 ---- logic/minecraft/LegacyInstance.cpp | 455 ---------------- logic/minecraft/LegacyInstance.h | 135 ----- logic/minecraft/LegacyUpdate.cpp | 395 -------------- logic/minecraft/LegacyUpdate.h | 70 --- logic/minecraft/LwjglVersionList.cpp | 189 ------- logic/minecraft/LwjglVersionList.h | 156 ------ logic/minecraft/OneSixInstance.cpp | 598 --------------------- logic/minecraft/OneSixInstance.h | 110 ---- logic/minecraft/OneSixProfileStrategy.cpp | 413 -------------- logic/minecraft/OneSixProfileStrategy.h | 26 - logic/minecraft/OneSixUpdate.cpp | 411 -------------- logic/minecraft/OneSixUpdate.h | 68 --- logic/minecraft/RawLibrary.h | 2 +- logic/minecraft/auth/AuthSession.cpp | 30 ++ logic/minecraft/auth/AuthSession.h | 51 ++ logic/minecraft/auth/MojangAccount.cpp | 278 ++++++++++ logic/minecraft/auth/MojangAccount.h | 173 ++++++ logic/minecraft/auth/MojangAccountList.cpp | 427 +++++++++++++++ logic/minecraft/auth/MojangAccountList.h | 201 +++++++ logic/minecraft/auth/YggdrasilTask.cpp | 255 +++++++++ logic/minecraft/auth/YggdrasilTask.h | 150 ++++++ logic/minecraft/auth/flows/AuthenticateTask.cpp | 202 +++++++ logic/minecraft/auth/flows/AuthenticateTask.h | 46 ++ logic/minecraft/auth/flows/RefreshTask.cpp | 144 +++++ logic/minecraft/auth/flows/RefreshTask.h | 44 ++ logic/minecraft/auth/flows/ValidateTask.cpp | 61 +++ logic/minecraft/auth/flows/ValidateTask.h | 47 ++ logic/minecraft/forge/ForgeInstaller.cpp | 442 +++++++++++++++ logic/minecraft/forge/ForgeInstaller.h | 52 ++ logic/minecraft/forge/ForgeMirror.h | 10 + logic/minecraft/forge/ForgeMirrors.cpp | 118 ++++ logic/minecraft/forge/ForgeMirrors.h | 61 +++ logic/minecraft/forge/ForgeVersion.cpp | 55 ++ logic/minecraft/forge/ForgeVersion.h | 42 ++ logic/minecraft/forge/ForgeVersionList.cpp | 450 ++++++++++++++++ logic/minecraft/forge/ForgeVersionList.h | 90 ++++ logic/minecraft/forge/ForgeXzDownload.cpp | 389 ++++++++++++++ logic/minecraft/forge/ForgeXzDownload.h | 66 +++ logic/minecraft/forge/LegacyForge.cpp | 56 ++ logic/minecraft/forge/LegacyForge.h | 25 + logic/minecraft/ftb/FTBPlugin.cpp | 395 ++++++++++++++ logic/minecraft/ftb/FTBPlugin.h | 13 + logic/minecraft/ftb/FTBProfileStrategy.cpp | 128 +++++ logic/minecraft/ftb/FTBProfileStrategy.h | 21 + logic/minecraft/ftb/FTBVersion.h | 32 ++ logic/minecraft/ftb/LegacyFTBInstance.cpp | 27 + logic/minecraft/ftb/LegacyFTBInstance.h | 13 + logic/minecraft/ftb/OneSixFTBInstance.cpp | 138 +++++ logic/minecraft/ftb/OneSixFTBInstance.h | 27 + logic/minecraft/legacy/LegacyInstance.cpp | 455 ++++++++++++++++ logic/minecraft/legacy/LegacyInstance.h | 135 +++++ logic/minecraft/legacy/LegacyUpdate.cpp | 395 ++++++++++++++ logic/minecraft/legacy/LegacyUpdate.h | 70 +++ logic/minecraft/legacy/LwjglVersionList.cpp | 189 +++++++ logic/minecraft/legacy/LwjglVersionList.h | 156 ++++++ logic/minecraft/liteloader/LiteLoaderInstaller.cpp | 141 +++++ logic/minecraft/liteloader/LiteLoaderInstaller.h | 39 ++ .../minecraft/liteloader/LiteLoaderVersionList.cpp | 275 ++++++++++ logic/minecraft/liteloader/LiteLoaderVersionList.h | 119 ++++ logic/minecraft/onesix/OneSixInstance.cpp | 598 +++++++++++++++++++++ logic/minecraft/onesix/OneSixInstance.h | 110 ++++ logic/minecraft/onesix/OneSixProfileStrategy.cpp | 414 ++++++++++++++ logic/minecraft/onesix/OneSixProfileStrategy.h | 26 + logic/minecraft/onesix/OneSixUpdate.cpp | 411 ++++++++++++++ logic/minecraft/onesix/OneSixUpdate.h | 68 +++ 127 files changed, 8448 insertions(+), 8444 deletions(-) delete mode 100644 logic/auth/AuthSession.cpp delete mode 100644 logic/auth/AuthSession.h delete mode 100644 logic/auth/MojangAccount.cpp delete mode 100644 logic/auth/MojangAccount.h delete mode 100644 logic/auth/MojangAccountList.cpp delete mode 100644 logic/auth/MojangAccountList.h delete mode 100644 logic/auth/YggdrasilTask.cpp delete mode 100644 logic/auth/YggdrasilTask.h delete mode 100644 logic/auth/flows/AuthenticateTask.cpp delete mode 100644 logic/auth/flows/AuthenticateTask.h delete mode 100644 logic/auth/flows/RefreshTask.cpp delete mode 100644 logic/auth/flows/RefreshTask.h delete mode 100644 logic/auth/flows/ValidateTask.cpp delete mode 100644 logic/auth/flows/ValidateTask.h delete mode 100644 logic/forge/ForgeInstaller.cpp delete mode 100644 logic/forge/ForgeInstaller.h delete mode 100644 logic/forge/ForgeMirror.h delete mode 100644 logic/forge/ForgeMirrors.cpp delete mode 100644 logic/forge/ForgeMirrors.h delete mode 100644 logic/forge/ForgeVersion.cpp delete mode 100644 logic/forge/ForgeVersion.h delete mode 100644 logic/forge/ForgeVersionList.cpp delete mode 100644 logic/forge/ForgeVersionList.h delete mode 100644 logic/forge/ForgeXzDownload.cpp delete mode 100644 logic/forge/ForgeXzDownload.h delete mode 100644 logic/forge/LegacyForge.cpp delete mode 100644 logic/forge/LegacyForge.h delete mode 100644 logic/ftb/FTBPlugin.cpp delete mode 100644 logic/ftb/FTBPlugin.h delete mode 100644 logic/ftb/FTBProfileStrategy.cpp delete mode 100644 logic/ftb/FTBProfileStrategy.h delete mode 100644 logic/ftb/FTBVersion.h delete mode 100644 logic/ftb/LegacyFTBInstance.cpp delete mode 100644 logic/ftb/LegacyFTBInstance.h delete mode 100644 logic/ftb/OneSixFTBInstance.cpp delete mode 100644 logic/ftb/OneSixFTBInstance.h delete mode 100644 logic/liteloader/LiteLoaderInstaller.cpp delete mode 100644 logic/liteloader/LiteLoaderInstaller.h delete mode 100644 logic/liteloader/LiteLoaderVersionList.cpp delete mode 100644 logic/liteloader/LiteLoaderVersionList.h delete mode 100644 logic/minecraft/LegacyInstance.cpp delete mode 100644 logic/minecraft/LegacyInstance.h delete mode 100644 logic/minecraft/LegacyUpdate.cpp delete mode 100644 logic/minecraft/LegacyUpdate.h delete mode 100644 logic/minecraft/LwjglVersionList.cpp delete mode 100644 logic/minecraft/LwjglVersionList.h delete mode 100644 logic/minecraft/OneSixInstance.cpp delete mode 100644 logic/minecraft/OneSixInstance.h delete mode 100644 logic/minecraft/OneSixProfileStrategy.cpp delete mode 100644 logic/minecraft/OneSixProfileStrategy.h delete mode 100644 logic/minecraft/OneSixUpdate.cpp delete mode 100644 logic/minecraft/OneSixUpdate.h create mode 100644 logic/minecraft/auth/AuthSession.cpp create mode 100644 logic/minecraft/auth/AuthSession.h create mode 100644 logic/minecraft/auth/MojangAccount.cpp create mode 100644 logic/minecraft/auth/MojangAccount.h create mode 100644 logic/minecraft/auth/MojangAccountList.cpp create mode 100644 logic/minecraft/auth/MojangAccountList.h create mode 100644 logic/minecraft/auth/YggdrasilTask.cpp create mode 100644 logic/minecraft/auth/YggdrasilTask.h create mode 100644 logic/minecraft/auth/flows/AuthenticateTask.cpp create mode 100644 logic/minecraft/auth/flows/AuthenticateTask.h create mode 100644 logic/minecraft/auth/flows/RefreshTask.cpp create mode 100644 logic/minecraft/auth/flows/RefreshTask.h create mode 100644 logic/minecraft/auth/flows/ValidateTask.cpp create mode 100644 logic/minecraft/auth/flows/ValidateTask.h create mode 100644 logic/minecraft/forge/ForgeInstaller.cpp create mode 100644 logic/minecraft/forge/ForgeInstaller.h create mode 100644 logic/minecraft/forge/ForgeMirror.h create mode 100644 logic/minecraft/forge/ForgeMirrors.cpp create mode 100644 logic/minecraft/forge/ForgeMirrors.h create mode 100644 logic/minecraft/forge/ForgeVersion.cpp create mode 100644 logic/minecraft/forge/ForgeVersion.h create mode 100644 logic/minecraft/forge/ForgeVersionList.cpp create mode 100644 logic/minecraft/forge/ForgeVersionList.h create mode 100644 logic/minecraft/forge/ForgeXzDownload.cpp create mode 100644 logic/minecraft/forge/ForgeXzDownload.h create mode 100644 logic/minecraft/forge/LegacyForge.cpp create mode 100644 logic/minecraft/forge/LegacyForge.h create mode 100644 logic/minecraft/ftb/FTBPlugin.cpp create mode 100644 logic/minecraft/ftb/FTBPlugin.h create mode 100644 logic/minecraft/ftb/FTBProfileStrategy.cpp create mode 100644 logic/minecraft/ftb/FTBProfileStrategy.h create mode 100644 logic/minecraft/ftb/FTBVersion.h create mode 100644 logic/minecraft/ftb/LegacyFTBInstance.cpp create mode 100644 logic/minecraft/ftb/LegacyFTBInstance.h create mode 100644 logic/minecraft/ftb/OneSixFTBInstance.cpp create mode 100644 logic/minecraft/ftb/OneSixFTBInstance.h create mode 100644 logic/minecraft/legacy/LegacyInstance.cpp create mode 100644 logic/minecraft/legacy/LegacyInstance.h create mode 100644 logic/minecraft/legacy/LegacyUpdate.cpp create mode 100644 logic/minecraft/legacy/LegacyUpdate.h create mode 100644 logic/minecraft/legacy/LwjglVersionList.cpp create mode 100644 logic/minecraft/legacy/LwjglVersionList.h create mode 100644 logic/minecraft/liteloader/LiteLoaderInstaller.cpp create mode 100644 logic/minecraft/liteloader/LiteLoaderInstaller.h create mode 100644 logic/minecraft/liteloader/LiteLoaderVersionList.cpp create mode 100644 logic/minecraft/liteloader/LiteLoaderVersionList.h create mode 100644 logic/minecraft/onesix/OneSixInstance.cpp create mode 100644 logic/minecraft/onesix/OneSixInstance.h create mode 100644 logic/minecraft/onesix/OneSixProfileStrategy.cpp create mode 100644 logic/minecraft/onesix/OneSixProfileStrategy.h create mode 100644 logic/minecraft/onesix/OneSixUpdate.cpp create mode 100644 logic/minecraft/onesix/OneSixUpdate.h diff --git a/application/InstancePageProvider.h b/application/InstancePageProvider.h index 1b283896..bfc60291 100644 --- a/application/InstancePageProvider.h +++ b/application/InstancePageProvider.h @@ -1,6 +1,6 @@ #pragma once -#include "minecraft/OneSixInstance.h" -#include "minecraft/LegacyInstance.h" +#include "minecraft/onesix/OneSixInstance.h" +#include "minecraft/legacy/LegacyInstance.h" #include #include "pages/BasePage.h" #include "pages/VersionPage.h" diff --git a/application/LaunchInteraction.cpp b/application/LaunchInteraction.cpp index 4033d87c..1caa054a 100644 --- a/application/LaunchInteraction.cpp +++ b/application/LaunchInteraction.cpp @@ -1,5 +1,5 @@ #include "LaunchInteraction.h" -#include +#include #include "MultiMC.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/AccountSelectDialog.h" @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index a9d8d1e9..1345835f 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -50,14 +50,12 @@ #include #include #include -#include -#include #include #include #include #include #include -#include +#include #include #include #include diff --git a/application/MainWindow.h b/application/MainWindow.h index 17de6966..363d163e 100644 --- a/application/MainWindow.h +++ b/application/MainWindow.h @@ -22,7 +22,7 @@ #include #include "BaseInstance.h" -#include "auth/MojangAccount.h" +#include "minecraft/auth/MojangAccount.h" #include "net/NetJob.h" #include "updater/GoUpdate.h" diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index d5779321..63a3b40b 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -20,13 +20,13 @@ #include #include "InstanceList.h" -#include "auth/MojangAccountList.h" +#include #include "icons/IconList.h" -#include "minecraft/LwjglVersionList.h" +//FIXME: get rid of this +#include "minecraft/legacy/LwjglVersionList.h" #include "minecraft/MinecraftVersionList.h" -#include "liteloader/LiteLoaderVersionList.h" - -#include "forge/ForgeVersionList.h" +#include "minecraft/liteloader/LiteLoaderVersionList.h" +#include "minecraft/forge/ForgeVersionList.h" #include "net/HttpMetaCache.h" #include "net/URLConstants.h" @@ -49,7 +49,7 @@ #include "handlers/IconResourceHandler.h" #include "handlers/WebResourceHandler.h" -#include "ftb/FTBPlugin.h" +#include "minecraft/ftb/FTBPlugin.h" #include #include diff --git a/application/dialogs/AccountSelectDialog.h b/application/dialogs/AccountSelectDialog.h index 21784032..7ae79314 100644 --- a/application/dialogs/AccountSelectDialog.h +++ b/application/dialogs/AccountSelectDialog.h @@ -19,7 +19,7 @@ #include -#include "auth/MojangAccountList.h" +#include "minecraft/auth/MojangAccountList.h" namespace Ui { diff --git a/application/dialogs/LoginDialog.cpp b/application/dialogs/LoginDialog.cpp index 7e0f7df8..d7a655fc 100644 --- a/application/dialogs/LoginDialog.cpp +++ b/application/dialogs/LoginDialog.cpp @@ -16,7 +16,7 @@ #include "LoginDialog.h" #include "ui_LoginDialog.h" -#include "auth/YggdrasilTask.h" +#include "minecraft/auth/YggdrasilTask.h" #include diff --git a/application/dialogs/LoginDialog.h b/application/dialogs/LoginDialog.h index 63c95fb8..74efeb77 100644 --- a/application/dialogs/LoginDialog.h +++ b/application/dialogs/LoginDialog.h @@ -18,7 +18,7 @@ #include #include -#include "auth/MojangAccount.h" +#include "minecraft/auth/MojangAccount.h" namespace Ui { diff --git a/application/pages/LegacyJarModPage.cpp b/application/pages/LegacyJarModPage.cpp index b329ba70..174176fb 100644 --- a/application/pages/LegacyJarModPage.cpp +++ b/application/pages/LegacyJarModPage.cpp @@ -23,7 +23,7 @@ #include "dialogs/ProgressDialog.h" #include "dialogs/ModEditDialogCommon.h" #include "minecraft/ModList.h" -#include "minecraft/LegacyInstance.h" +#include "minecraft/legacy/LegacyInstance.h" #include "Env.h" #include #include "MultiMC.h" diff --git a/application/pages/LegacyUpgradePage.cpp b/application/pages/LegacyUpgradePage.cpp index 49998c50..14cb916d 100644 --- a/application/pages/LegacyUpgradePage.cpp +++ b/application/pages/LegacyUpgradePage.cpp @@ -1,7 +1,7 @@ #include "LegacyUpgradePage.h" #include "ui_LegacyUpgradePage.h" -#include "minecraft/LegacyInstance.h" +#include "minecraft/legacy/LegacyInstance.h" LegacyUpgradePage::LegacyUpgradePage(LegacyInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst) diff --git a/application/pages/LegacyUpgradePage.h b/application/pages/LegacyUpgradePage.h index 8d1131c8..ff9965f1 100644 --- a/application/pages/LegacyUpgradePage.h +++ b/application/pages/LegacyUpgradePage.h @@ -17,7 +17,7 @@ #include -#include "minecraft/OneSixInstance.h" +#include "minecraft/legacy/LegacyInstance.h" #include "pages/BasePage.h" #include diff --git a/application/pages/ModFolderPage.h b/application/pages/ModFolderPage.h index 0870aa64..23b2f67d 100644 --- a/application/pages/ModFolderPage.h +++ b/application/pages/ModFolderPage.h @@ -17,7 +17,7 @@ #include -#include "minecraft/OneSixInstance.h" +#include "minecraft/onesix/OneSixInstance.h" #include "BasePage.h" #include diff --git a/application/pages/VersionPage.cpp b/application/pages/VersionPage.cpp index f01a2d62..42e4a9bf 100644 --- a/application/pages/VersionPage.cpp +++ b/application/pages/VersionPage.cpp @@ -36,14 +36,14 @@ #include #include "minecraft/MinecraftProfile.h" -#include "forge/ForgeVersionList.h" -#include "forge/ForgeInstaller.h" -#include "liteloader/LiteLoaderVersionList.h" -#include "liteloader/LiteLoaderInstaller.h" -#include "auth/MojangAccountList.h" +#include "minecraft/forge/ForgeVersionList.h" +#include "minecraft/forge/ForgeInstaller.h" +#include "minecraft/liteloader/LiteLoaderVersionList.h" +#include "minecraft/liteloader/LiteLoaderInstaller.h" +#include "minecraft/auth/MojangAccountList.h" #include "minecraft/Mod.h" -#include -#include +#include "minecraft/MinecraftVersion.h" +#include "minecraft/MinecraftVersionList.h" #include "icons/IconList.h" #include "Exception.h" diff --git a/application/pages/VersionPage.h b/application/pages/VersionPage.h index 216bc30e..e7b07ac3 100644 --- a/application/pages/VersionPage.h +++ b/application/pages/VersionPage.h @@ -17,7 +17,7 @@ #include -#include "minecraft/OneSixInstance.h" +#include "minecraft/onesix/OneSixInstance.h" #include "BasePage.h" namespace Ui diff --git a/application/pages/WorldListPage.h b/application/pages/WorldListPage.h index 7a7cf591..8a9fc16f 100644 --- a/application/pages/WorldListPage.h +++ b/application/pages/WorldListPage.h @@ -17,7 +17,7 @@ #include -#include "minecraft/OneSixInstance.h" +#include "minecraft/onesix/OneSixInstance.h" #include "BasePage.h" #include diff --git a/application/pages/global/AccountListPage.cpp b/application/pages/global/AccountListPage.cpp index 62267f13..84d317c1 100644 --- a/application/pages/global/AccountListPage.cpp +++ b/application/pages/global/AccountListPage.cpp @@ -29,7 +29,7 @@ #include "dialogs/LoginDialog.h" #include "dialogs/CustomMessageBox.h" #include "tasks/Task.h" -#include "auth/YggdrasilTask.h" +#include "minecraft/auth/YggdrasilTask.h" #include "MultiMC.h" diff --git a/application/pages/global/AccountListPage.h b/application/pages/global/AccountListPage.h index 7803e044..5701dfcb 100644 --- a/application/pages/global/AccountListPage.h +++ b/application/pages/global/AccountListPage.h @@ -20,7 +20,7 @@ #include "pages/BasePage.h" -#include "auth/MojangAccountList.h" +#include "minecraft/auth/MojangAccountList.h" #include "MultiMC.h" namespace Ui diff --git a/logic/BaseInstaller.cpp b/logic/BaseInstaller.cpp index d8e83bb2..cb762ebd 100644 --- a/logic/BaseInstaller.cpp +++ b/logic/BaseInstaller.cpp @@ -16,7 +16,7 @@ #include #include "BaseInstaller.h" -#include "minecraft/OneSixInstance.h" +#include "minecraft/onesix/OneSixInstance.h" BaseInstaller::BaseInstaller() { diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index cc8ebb02..392cb3d9 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -24,7 +24,7 @@ #include "settings/INIFile.h" #include "BaseVersionList.h" -#include "auth/MojangAccount.h" +#include "minecraft/auth/MojangAccount.h" #include "launch/MessageLevel.h" #include "pathmatcher/IPathMatcher.h" diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index 0a6cbbf6..40311baf 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -95,20 +95,20 @@ set(LOGIC_SOURCES net/URLConstants.cpp # Yggdrasil login stuff - auth/AuthSession.h - auth/AuthSession.cpp - auth/MojangAccountList.h - auth/MojangAccountList.cpp - auth/MojangAccount.h - auth/MojangAccount.cpp - auth/YggdrasilTask.h - auth/YggdrasilTask.cpp - auth/flows/AuthenticateTask.h - auth/flows/AuthenticateTask.cpp - auth/flows/RefreshTask.cpp - auth/flows/RefreshTask.cpp - auth/flows/ValidateTask.h - auth/flows/ValidateTask.cpp + minecraft/auth/AuthSession.h + minecraft/auth/AuthSession.cpp + minecraft/auth/MojangAccountList.h + minecraft/auth/MojangAccountList.cpp + minecraft/auth/MojangAccount.h + minecraft/auth/MojangAccount.cpp + minecraft/auth/YggdrasilTask.h + minecraft/auth/YggdrasilTask.cpp + minecraft/auth/flows/AuthenticateTask.h + minecraft/auth/flows/AuthenticateTask.cpp + minecraft/auth/flows/RefreshTask.cpp + minecraft/auth/flows/RefreshTask.cpp + minecraft/auth/flows/ValidateTask.h + minecraft/auth/flows/ValidateTask.cpp # Game launch logic launch/steps/CheckJava.cpp @@ -157,16 +157,18 @@ set(LOGIC_SOURCES status/StatusChecker.cpp # Minecraft support - minecraft/OneSixUpdate.h - minecraft/OneSixUpdate.cpp - minecraft/OneSixInstance.h - minecraft/OneSixInstance.cpp - minecraft/LegacyUpdate.h - minecraft/LegacyUpdate.cpp - minecraft/LegacyInstance.h - minecraft/LegacyInstance.cpp - minecraft/LwjglVersionList.h - minecraft/LwjglVersionList.cpp + minecraft/onesix/OneSixUpdate.h + minecraft/onesix/OneSixUpdate.cpp + minecraft/onesix/OneSixInstance.h + minecraft/onesix/OneSixInstance.cpp + minecraft/onesix/OneSixProfileStrategy.cpp + minecraft/onesix/OneSixProfileStrategy.h + minecraft/legacy/LegacyUpdate.h + minecraft/legacy/LegacyUpdate.cpp + minecraft/legacy/LegacyInstance.h + minecraft/legacy/LegacyInstance.cpp + minecraft/legacy/LwjglVersionList.h + minecraft/legacy/LwjglVersionList.cpp minecraft/SkinUtils.h minecraft/SkinUtils.cpp minecraft/GradleSpecifier.h @@ -181,8 +183,6 @@ set(LOGIC_SOURCES minecraft/MinecraftVersionList.cpp minecraft/MinecraftVersionList.h minecraft/NullProfileStrategy.h - minecraft/OneSixProfileStrategy.cpp - minecraft/OneSixProfileStrategy.h minecraft/OneSixRule.cpp minecraft/OneSixRule.h minecraft/OpSys.cpp @@ -211,14 +211,14 @@ set(LOGIC_SOURCES minecraft/WorldList.cpp # FTB - ftb/OneSixFTBInstance.h - ftb/OneSixFTBInstance.cpp - ftb/LegacyFTBInstance.h - ftb/LegacyFTBInstance.cpp - ftb/FTBProfileStrategy.h - ftb/FTBProfileStrategy.cpp - ftb/FTBPlugin.h - ftb/FTBPlugin.cpp + minecraft/ftb/OneSixFTBInstance.h + minecraft/ftb/OneSixFTBInstance.cpp + minecraft/ftb/LegacyFTBInstance.h + minecraft/ftb/LegacyFTBInstance.cpp + minecraft/ftb/FTBProfileStrategy.h + minecraft/ftb/FTBProfileStrategy.cpp + minecraft/ftb/FTBPlugin.h + minecraft/ftb/FTBPlugin.cpp # A Recursive file system watcher RecursiveFileSystemWatcher.h @@ -278,25 +278,25 @@ set(LOGIC_SOURCES minecraft/AssetsUtils.cpp # Forge and all things forge related - forge/ForgeVersion.h - forge/ForgeVersion.cpp - forge/ForgeVersionList.h - forge/ForgeVersionList.cpp - forge/ForgeMirror.h - forge/ForgeMirrors.h - forge/ForgeMirrors.cpp - forge/ForgeXzDownload.h - forge/ForgeXzDownload.cpp - forge/LegacyForge.h - forge/LegacyForge.cpp - forge/ForgeInstaller.h - forge/ForgeInstaller.cpp + minecraft/forge/ForgeVersion.h + minecraft/forge/ForgeVersion.cpp + minecraft/forge/ForgeVersionList.h + minecraft/forge/ForgeVersionList.cpp + minecraft/forge/ForgeMirror.h + minecraft/forge/ForgeMirrors.h + minecraft/forge/ForgeMirrors.cpp + minecraft/forge/ForgeXzDownload.h + minecraft/forge/ForgeXzDownload.cpp + minecraft/forge/LegacyForge.h + minecraft/forge/LegacyForge.cpp + minecraft/forge/ForgeInstaller.h + minecraft/forge/ForgeInstaller.cpp # Liteloader and related things - liteloader/LiteLoaderInstaller.h - liteloader/LiteLoaderInstaller.cpp - liteloader/LiteLoaderVersionList.h - liteloader/LiteLoaderVersionList.cpp + minecraft/liteloader/LiteLoaderInstaller.h + minecraft/liteloader/LiteLoaderInstaller.cpp + minecraft/liteloader/LiteLoaderVersionList.h + minecraft/liteloader/LiteLoaderVersionList.cpp # Translations trans/TranslationDownloader.h diff --git a/logic/InstanceList.cpp b/logic/InstanceList.cpp index a8acdf05..8197fe24 100644 --- a/logic/InstanceList.cpp +++ b/logic/InstanceList.cpp @@ -31,11 +31,11 @@ #include "BaseInstance.h" //FIXME: this really doesn't belong *here* -#include "minecraft/OneSixInstance.h" -#include "minecraft/LegacyInstance.h" +#include "minecraft/onesix/OneSixInstance.h" +#include "minecraft/legacy/LegacyInstance.h" +#include "minecraft/ftb/FTBPlugin.h" #include "minecraft/MinecraftVersion.h" #include "settings/INISettingsObject.h" -#include "ftb/FTBPlugin.h" #include "NullInstance.h" #include "FileSystem.h" #include "pathmatcher/RegexpMatcher.h" diff --git a/logic/auth/AuthSession.cpp b/logic/auth/AuthSession.cpp deleted file mode 100644 index 8758bfbd..00000000 --- a/logic/auth/AuthSession.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "AuthSession.h" -#include -#include -#include -#include - -QString AuthSession::serializeUserProperties() -{ - QJsonObject userAttrs; - for (auto key : u.properties.keys()) - { - auto array = QJsonArray::fromStringList(u.properties.values(key)); - userAttrs.insert(key, array); - } - QJsonDocument value(userAttrs); - return value.toJson(QJsonDocument::Compact); - -} - -bool AuthSession::MakeOffline(QString offline_playername) -{ - if (status != PlayableOffline && status != PlayableOnline) - { - return false; - } - session = "-"; - player_name = offline_playername; - status = PlayableOffline; - return true; -} diff --git a/logic/auth/AuthSession.h b/logic/auth/AuthSession.h deleted file mode 100644 index dede90a9..00000000 --- a/logic/auth/AuthSession.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "multimc_logic_export.h" - -struct User -{ - QString id; - QMultiMap properties; -}; - -struct MULTIMC_LOGIC_EXPORT AuthSession -{ - bool MakeOffline(QString offline_playername); - - QString serializeUserProperties(); - - enum Status - { - Undetermined, - RequiresPassword, - PlayableOffline, - PlayableOnline - } status = Undetermined; - - User u; - - // client token - QString client_token; - // account user name - QString username; - // combined session ID - QString session; - // volatile auth token - QString access_token; - // profile name - QString player_name; - // profile ID - QString uuid; - // 'legacy' or 'mojang', depending on account type - QString user_type; - // Did the auth server reply? - bool auth_server_online = false; - // Did the user request online mode? - bool wants_online = true; -}; - -typedef std::shared_ptr AuthSessionPtr; diff --git a/logic/auth/MojangAccount.cpp b/logic/auth/MojangAccount.cpp deleted file mode 100644 index 69a24c09..00000000 --- a/logic/auth/MojangAccount.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Authors: Orochimarufan - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "MojangAccount.h" -#include "flows/RefreshTask.h" -#include "flows/AuthenticateTask.h" - -#include -#include -#include -#include -#include -#include - -#include - -MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object) -{ - // The JSON object must at least have a username for it to be valid. - if (!object.value("username").isString()) - { - qCritical() << "Can't load Mojang account info from JSON object. Username field is " - "missing or of the wrong type."; - return nullptr; - } - - QString username = object.value("username").toString(""); - QString clientToken = object.value("clientToken").toString(""); - QString accessToken = object.value("accessToken").toString(""); - - QJsonArray profileArray = object.value("profiles").toArray(); - if (profileArray.size() < 1) - { - qCritical() << "Can't load Mojang account with username \"" << username - << "\". No profiles found."; - return nullptr; - } - - QList profiles; - for (QJsonValue profileVal : profileArray) - { - QJsonObject profileObject = profileVal.toObject(); - QString id = profileObject.value("id").toString(""); - QString name = profileObject.value("name").toString(""); - bool legacy = profileObject.value("legacy").toBool(false); - if (id.isEmpty() || name.isEmpty()) - { - qWarning() << "Unable to load a profile because it was missing an ID or a name."; - continue; - } - profiles.append({id, name, legacy}); - } - - MojangAccountPtr account(new MojangAccount()); - if (object.value("user").isObject()) - { - User u; - QJsonObject userStructure = object.value("user").toObject(); - u.id = userStructure.value("id").toString(); - /* - QJsonObject propMap = userStructure.value("properties").toObject(); - for(auto key: propMap.keys()) - { - auto values = propMap.operator[](key).toArray(); - for(auto value: values) - u.properties.insert(key, value.toString()); - } - */ - account->m_user = u; - } - account->m_username = username; - account->m_clientToken = clientToken; - account->m_accessToken = accessToken; - account->m_profiles = profiles; - - // Get the currently selected profile. - QString currentProfile = object.value("activeProfile").toString(""); - if (!currentProfile.isEmpty()) - account->setCurrentProfile(currentProfile); - - return account; -} - -MojangAccountPtr MojangAccount::createFromUsername(const QString &username) -{ - MojangAccountPtr account(new MojangAccount()); - account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]")); - account->m_username = username; - return account; -} - -QJsonObject MojangAccount::saveToJson() const -{ - QJsonObject json; - json.insert("username", m_username); - json.insert("clientToken", m_clientToken); - json.insert("accessToken", m_accessToken); - - QJsonArray profileArray; - for (AccountProfile profile : m_profiles) - { - QJsonObject profileObj; - profileObj.insert("id", profile.id); - profileObj.insert("name", profile.name); - profileObj.insert("legacy", profile.legacy); - profileArray.append(profileObj); - } - json.insert("profiles", profileArray); - - QJsonObject userStructure; - { - userStructure.insert("id", m_user.id); - /* - QJsonObject userAttrs; - for(auto key: m_user.properties.keys()) - { - auto array = QJsonArray::fromStringList(m_user.properties.values(key)); - userAttrs.insert(key, array); - } - userStructure.insert("properties", userAttrs); - */ - } - json.insert("user", userStructure); - - if (m_currentProfile != -1) - json.insert("activeProfile", currentProfile()->id); - - return json; -} - -bool MojangAccount::setCurrentProfile(const QString &profileId) -{ - for (int i = 0; i < m_profiles.length(); i++) - { - if (m_profiles[i].id == profileId) - { - m_currentProfile = i; - return true; - } - } - return false; -} - -const AccountProfile *MojangAccount::currentProfile() const -{ - if (m_currentProfile == -1) - return nullptr; - return &m_profiles[m_currentProfile]; -} - -AccountStatus MojangAccount::accountStatus() const -{ - if (m_accessToken.isEmpty()) - return NotVerified; - else - return Verified; -} - -std::shared_ptr MojangAccount::login(AuthSessionPtr session, - QString password) -{ - Q_ASSERT(m_currentTask.get() == nullptr); - - // take care of the true offline status - if (accountStatus() == NotVerified && password.isEmpty()) - { - if (session) - { - session->status = AuthSession::RequiresPassword; - fillSession(session); - } - return nullptr; - } - - if (password.isEmpty()) - { - m_currentTask.reset(new RefreshTask(this)); - } - else - { - m_currentTask.reset(new AuthenticateTask(this, password)); - } - m_currentTask->assignSession(session); - - connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); - connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); - return m_currentTask; -} - -void MojangAccount::authSucceeded() -{ - auto session = m_currentTask->getAssignedSession(); - if (session) - { - session->status = - session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline; - fillSession(session); - session->auth_server_online = true; - } - m_currentTask.reset(); - emit changed(); -} - -void MojangAccount::authFailed(QString reason) -{ - auto session = m_currentTask->getAssignedSession(); - // This is emitted when the yggdrasil tasks time out or are cancelled. - // -> we treat the error as no-op - if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT) - { - if (session) - { - session->status = accountStatus() == Verified ? AuthSession::PlayableOffline - : AuthSession::RequiresPassword; - session->auth_server_online = false; - fillSession(session); - } - } - else - { - m_accessToken = QString(); - emit changed(); - if (session) - { - session->status = AuthSession::RequiresPassword; - session->auth_server_online = true; - fillSession(session); - } - } - m_currentTask.reset(); -} - -void MojangAccount::fillSession(AuthSessionPtr session) -{ - // the user name. you have to have an user name - session->username = m_username; - // volatile auth token - session->access_token = m_accessToken; - // the semi-permanent client token - session->client_token = m_clientToken; - if (currentProfile()) - { - // profile name - session->player_name = currentProfile()->name; - // profile ID - session->uuid = currentProfile()->id; - // 'legacy' or 'mojang', depending on account type - session->user_type = currentProfile()->legacy ? "legacy" : "mojang"; - if (!session->access_token.isEmpty()) - { - session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id; - } - else - { - session->session = "-"; - } - } - else - { - session->player_name = "Player"; - session->session = "-"; - } - session->u = user(); -} diff --git a/logic/auth/MojangAccount.h b/logic/auth/MojangAccount.h deleted file mode 100644 index 2de0c19c..00000000 --- a/logic/auth/MojangAccount.h +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include "AuthSession.h" - -#include "multimc_logic_export.h" - -class Task; -class YggdrasilTask; -class MojangAccount; - -typedef std::shared_ptr MojangAccountPtr; -Q_DECLARE_METATYPE(MojangAccountPtr) - -/** - * A profile within someone's Mojang account. - * - * Currently, the profile system has not been implemented by Mojang yet, - * but we might as well add some things for it in MultiMC right now so - * we don't have to rip the code to pieces to add it later. - */ -struct AccountProfile -{ - QString id; - QString name; - bool legacy; -}; - -enum AccountStatus -{ - NotVerified, - Verified -}; - -/** - * Object that stores information about a certain Mojang account. - * - * Said information may include things such as that account's username, client token, and access - * token if the user chose to stay logged in. - */ -class MULTIMC_LOGIC_EXPORT MojangAccount : public QObject -{ - Q_OBJECT -public: /* construction */ - //! Do not copy accounts. ever. - explicit MojangAccount(const MojangAccount &other, QObject *parent) = delete; - - //! Default constructor - explicit MojangAccount(QObject *parent = 0) : QObject(parent) {}; - - //! Creates an empty account for the specified user name. - static MojangAccountPtr createFromUsername(const QString &username); - - //! Loads a MojangAccount from the given JSON object. - static MojangAccountPtr loadFromJson(const QJsonObject &json); - - //! Saves a MojangAccount to a JSON object and returns it. - QJsonObject saveToJson() const; - -public: /* manipulation */ - /** - * Sets the currently selected profile to the profile with the given ID string. - * If profileId is not in the list of available profiles, the function will simply return - * false. - */ - bool setCurrentProfile(const QString &profileId); - - /** - * Attempt to login. Empty password means we use the token. - * If the attempt fails because we already are performing some task, it returns false. - */ - std::shared_ptr login(AuthSessionPtr session, - QString password = QString()); - -public: /* queries */ - const QString &username() const - { - return m_username; - } - - const QString &clientToken() const - { - return m_clientToken; - } - - const QString &accessToken() const - { - return m_accessToken; - } - - const QList &profiles() const - { - return m_profiles; - } - - const User &user() - { - return m_user; - } - - //! Returns the currently selected profile (if none, returns nullptr) - const AccountProfile *currentProfile() const; - - //! Returns whether the account is NotVerified, Verified or Online - AccountStatus accountStatus() const; - -signals: - /** - * This signal is emitted when the account changes - */ - void changed(); - - // TODO: better signalling for the various possible state changes - especially errors - -protected: /* variables */ - QString m_username; - - // Used to identify the client - the user can have multiple clients for the same account - // Think: different launchers, all connecting to the same account/profile - QString m_clientToken; - - // Blank if not logged in. - QString m_accessToken; - - // Index of the selected profile within the list of available - // profiles. -1 if nothing is selected. - int m_currentProfile = -1; - - // List of available profiles. - QList m_profiles; - - // the user structure, whatever it is. - User m_user; - - // current task we are executing here - std::shared_ptr m_currentTask; - -private -slots: - void authSucceeded(); - void authFailed(QString reason); - -private: - void fillSession(AuthSessionPtr session); - -public: - friend class YggdrasilTask; - friend class AuthenticateTask; - friend class ValidateTask; - friend class RefreshTask; -}; diff --git a/logic/auth/MojangAccountList.cpp b/logic/auth/MojangAccountList.cpp deleted file mode 100644 index dac3d67f..00000000 --- a/logic/auth/MojangAccountList.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "auth/MojangAccountList.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "auth/MojangAccount.h" -#include - -#define ACCOUNT_LIST_FORMAT_VERSION 2 - -MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent) -{ -} - -MojangAccountPtr MojangAccountList::findAccount(const QString &username) const -{ - for (int i = 0; i < count(); i++) - { - MojangAccountPtr account = at(i); - if (account->username() == username) - return account; - } - return nullptr; -} - -const MojangAccountPtr MojangAccountList::at(int i) const -{ - return MojangAccountPtr(m_accounts.at(i)); -} - -void MojangAccountList::addAccount(const MojangAccountPtr account) -{ - beginResetModel(); - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); - m_accounts.append(account); - endResetModel(); - onListChanged(); -} - -void MojangAccountList::removeAccount(const QString &username) -{ - beginResetModel(); - for (auto account : m_accounts) - { - if (account->username() == username) - { - m_accounts.removeOne(account); - return; - } - } - endResetModel(); - onListChanged(); -} - -void MojangAccountList::removeAccount(QModelIndex index) -{ - beginResetModel(); - m_accounts.removeAt(index.row()); - endResetModel(); - onListChanged(); -} - -MojangAccountPtr MojangAccountList::activeAccount() const -{ - return m_activeAccount; -} - -void MojangAccountList::setActiveAccount(const QString &username) -{ - beginResetModel(); - if (username.isEmpty()) - { - m_activeAccount = nullptr; - } - else - { - for (MojangAccountPtr account : m_accounts) - { - if (account->username() == username) - m_activeAccount = account; - } - } - endResetModel(); - onActiveChanged(); -} - -void MojangAccountList::accountChanged() -{ - // the list changed. there is no doubt. - onListChanged(); -} - -void MojangAccountList::onListChanged() -{ - if (m_autosave) - // TODO: Alert the user if this fails. - saveList(); - - emit listChanged(); -} - -void MojangAccountList::onActiveChanged() -{ - if (m_autosave) - saveList(); - - emit activeAccountChanged(); -} - -int MojangAccountList::count() const -{ - return m_accounts.count(); -} - -QVariant MojangAccountList::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() > count()) - return QVariant(); - - MojangAccountPtr account = at(index.row()); - - switch (role) - { - case Qt::DisplayRole: - switch (index.column()) - { - case NameColumn: - return account->username(); - - default: - return QVariant(); - } - - case Qt::ToolTipRole: - return account->username(); - - case PointerRole: - return qVariantFromValue(account); - - case Qt::CheckStateRole: - switch (index.column()) - { - case ActiveColumn: - return account == m_activeAccount; - } - - default: - return QVariant(); - } -} - -QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const -{ - switch (role) - { - case Qt::DisplayRole: - switch (section) - { - case ActiveColumn: - return tr("Active?"); - - case NameColumn: - return tr("Name"); - - default: - return QVariant(); - } - - case Qt::ToolTipRole: - switch (section) - { - case NameColumn: - return tr("The name of the version."); - - default: - return QVariant(); - } - - default: - return QVariant(); - } -} - -int MojangAccountList::rowCount(const QModelIndex &parent) const -{ - // Return count - return count(); -} - -int MojangAccountList::columnCount(const QModelIndex &parent) const -{ - return 2; -} - -Qt::ItemFlags MojangAccountList::flags(const QModelIndex &index) const -{ - if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -bool MojangAccountList::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid()) - { - return false; - } - - if(role == Qt::CheckStateRole) - { - if(value == Qt::Checked) - { - MojangAccountPtr account = this->at(index.row()); - this->setActiveAccount(account->username()); - } - } - - emit dataChanged(index, index); - return true; -} - -void MojangAccountList::updateListData(QList versions) -{ - beginResetModel(); - m_accounts = versions; - endResetModel(); -} - -bool MojangAccountList::loadList(const QString &filePath) -{ - QString path = filePath; - if (path.isEmpty()) - path = m_listFilePath; - if (path.isEmpty()) - { - qCritical() << "Can't load Mojang account list. No file path given and no default set."; - return false; - } - - QFile file(path); - - // Try to open the file and fail if we can't. - // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::ReadOnly)) - { - qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8(); - return false; - } - - // Read the file and close it. - QByteArray jsonData = file.readAll(); - file.close(); - - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); - - // Fail if the JSON is invalid. - if (parseError.error != QJsonParseError::NoError) - { - qCritical() << QString("Failed to parse account list file: %1 at offset %2") - .arg(parseError.errorString(), QString::number(parseError.offset)) - .toUtf8(); - return false; - } - - // Make sure the root is an object. - if (!jsonDoc.isObject()) - { - qCritical() << "Invalid account list JSON: Root should be an array."; - return false; - } - - QJsonObject root = jsonDoc.object(); - - // Make sure the format version matches. - if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION) - { - QString newName = "accounts-old.json"; - qWarning() << "Format version mismatch when loading account list. Existing one will be renamed to" - << newName; - - // Attempt to rename the old version. - file.rename(newName); - return false; - } - - // Now, load the accounts array. - beginResetModel(); - QJsonArray accounts = root.value("accounts").toArray(); - for (QJsonValue accountVal : accounts) - { - QJsonObject accountObj = accountVal.toObject(); - MojangAccountPtr account = MojangAccount::loadFromJson(accountObj); - if (account.get() != nullptr) - { - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); - m_accounts.append(account); - } - else - { - qWarning() << "Failed to load an account."; - } - } - // Load the active account. - m_activeAccount = findAccount(root.value("activeAccount").toString("")); - endResetModel(); - return true; -} - -bool MojangAccountList::saveList(const QString &filePath) -{ - QString path(filePath); - if (path.isEmpty()) - path = m_listFilePath; - if (path.isEmpty()) - { - qCritical() << "Can't save Mojang account list. No file path given and no default set."; - return false; - } - - // make sure the parent folder exists - if(!FS::ensureFilePathExists(path)) - return false; - - // make sure the file wasn't overwritten with a folder before (fixes a bug) - QFileInfo finfo(path); - if(finfo.isDir()) - { - QDir badDir(path); - badDir.removeRecursively(); - } - - qDebug() << "Writing account list to" << path; - - qDebug() << "Building JSON data structure."; - // Build the JSON document to write to the list file. - QJsonObject root; - - root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION); - - // Build a list of accounts. - qDebug() << "Building account array."; - QJsonArray accounts; - for (MojangAccountPtr account : m_accounts) - { - QJsonObject accountObj = account->saveToJson(); - accounts.append(accountObj); - } - - // Insert the account list into the root object. - root.insert("accounts", accounts); - - if(m_activeAccount) - { - // Save the active account. - root.insert("activeAccount", m_activeAccount->username()); - } - - // Create a JSON document object to convert our JSON to bytes. - QJsonDocument doc(root); - - // Now that we're done building the JSON object, we can write it to the file. - qDebug() << "Writing account list to file."; - QFile file(path); - - // Try to open the file and fail if we can't. - // TODO: We should probably report this error to the user. - if (!file.open(QIODevice::WriteOnly)) - { - qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8(); - return false; - } - - // Write the JSON to the file. - file.write(doc.toJson()); - file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser); - file.close(); - - qDebug() << "Saved account list to" << path; - - return true; -} - -void MojangAccountList::setListFilePath(QString path, bool autosave) -{ - m_listFilePath = path; - m_autosave = autosave; -} - -bool MojangAccountList::anyAccountIsValid() -{ - for(auto account:m_accounts) - { - if(account->accountStatus() != NotVerified) - return true; - } - return false; -} diff --git a/logic/auth/MojangAccountList.h b/logic/auth/MojangAccountList.h deleted file mode 100644 index 49b71fab..00000000 --- a/logic/auth/MojangAccountList.h +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include - -#include "auth/MojangAccount.h" - -#include "multimc_logic_export.h" - -/*! - * \brief List of available Mojang accounts. - * This should be loaded in the background by MultiMC on startup. - * - * This class also inherits from QAbstractListModel. Methods from that - * class determine how this list shows up in a list view. Said methods - * all have a default implementation, but they can be overridden by subclasses to - * change the behavior of the list. - */ -class MULTIMC_LOGIC_EXPORT MojangAccountList : public QAbstractListModel -{ - Q_OBJECT -public: - enum ModelRoles - { - PointerRole = 0x34B1CB48 - }; - - enum VListColumns - { - // TODO: Add icon column. - - // First column - Active? - ActiveColumn = 0, - - // Second column - Name - NameColumn, - }; - - explicit MojangAccountList(QObject *parent = 0); - - //! Gets the account at the given index. - virtual const MojangAccountPtr at(int i) const; - - //! Returns the number of accounts in the list. - virtual int count() const; - - //////// List Model Functions //////// - virtual QVariant data(const QModelIndex &index, int role) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; - virtual int rowCount(const QModelIndex &parent) const; - virtual int columnCount(const QModelIndex &parent) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role); - - /*! - * Adds a the given Mojang account to the account list. - */ - virtual void addAccount(const MojangAccountPtr account); - - /*! - * Removes the mojang account with the given username from the account list. - */ - virtual void removeAccount(const QString &username); - - /*! - * Removes the account at the given QModelIndex. - */ - virtual void removeAccount(QModelIndex index); - - /*! - * \brief Finds an account by its username. - * \param The username of the account to find. - * \return A const pointer to the account with the given username. NULL if - * one doesn't exist. - */ - virtual MojangAccountPtr findAccount(const QString &username) const; - - /*! - * Sets the default path to save the list file to. - * If autosave is true, this list will automatically save to the given path whenever it changes. - * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately - * after calling this function to ensure an autosaved change doesn't overwrite the list you intended - * to load. - */ - virtual void setListFilePath(QString path, bool autosave = false); - - /*! - * \brief Loads the account list from the given file path. - * If the given file is an empty string (default), will load from the default account list file. - * \return True if successful, otherwise false. - */ - virtual bool loadList(const QString &file = ""); - - /*! - * \brief Saves the account list to the given file. - * If the given file is an empty string (default), will save from the default account list file. - * \return True if successful, otherwise false. - */ - virtual bool saveList(const QString &file = ""); - - /*! - * \brief Gets a pointer to the account that the user has selected as their "active" account. - * Which account is active can be overridden on a per-instance basis, but this will return the one that - * is set as active globally. - * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer. - */ - virtual MojangAccountPtr activeAccount() const; - - /*! - * Sets the given account as the current active account. - * If the username given is an empty string, sets the active account to nothing. - */ - virtual void setActiveAccount(const QString &username); - - /*! - * Returns true if any of the account is at least Validated - */ - bool anyAccountIsValid(); - -signals: - /*! - * Signal emitted to indicate that the account list has changed. - * This will also fire if the value of an element in the list changes (will be implemented - * later). - */ - void listChanged(); - - /*! - * Signal emitted to indicate that the active account has changed. - */ - void activeAccountChanged(); - -public -slots: - /** - * This is called when one of the accounts changes and the list needs to be updated - */ - void accountChanged(); - -protected: - /*! - * Called whenever the list changes. - * This emits the listChanged() signal and autosaves the list (if autosave is enabled). - */ - void onListChanged(); - - /*! - * Called whenever the active account changes. - * Emits the activeAccountChanged() signal and autosaves the list if enabled. - */ - void onActiveChanged(); - - QList m_accounts; - - /*! - * Account that is currently active. - */ - MojangAccountPtr m_activeAccount; - - //! Path to the account list file. Empty string if there isn't one. - QString m_listFilePath; - - /*! - * If true, the account list will automatically save to the account list path when it changes. - * Ignored if m_listFilePath is blank. - */ - bool m_autosave = false; - -protected -slots: - /*! - * Updates this list with the given list of accounts. - * This is done by copying each account in the given list and inserting it - * into this one. - * We need to do this so that we can set the parents of the accounts are set to this - * account list. This can't be done in the load task, because the accounts the load - * task creates are on the load task's thread and Qt won't allow their parents - * to be set to something created on another thread. - * To get around that problem, we invoke this method on the GUI thread, which - * then copies the accounts and sets their parents correctly. - * \param accounts List of accounts whose parents should be set. - */ - virtual void updateListData(QList versions); -}; diff --git a/logic/auth/YggdrasilTask.cpp b/logic/auth/YggdrasilTask.cpp deleted file mode 100644 index 929ab0bf..00000000 --- a/logic/auth/YggdrasilTask.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent) - : Task(parent), m_account(account) -{ - changeState(STATE_CREATED); -} - -void YggdrasilTask::executeTask() -{ - changeState(STATE_SENDING_REQUEST); - - // Get the content of the request we're going to send to the server. - QJsonDocument doc(getRequestContent()); - - auto worker = ENV.qnam(); - QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint()); - QNetworkRequest netRequest(reqUrl); - netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - QByteArray requestData = doc.toJson(); - m_netReply = worker->post(netRequest, requestData); - connect(m_netReply, &QNetworkReply::finished, this, &YggdrasilTask::processReply); - connect(m_netReply, &QNetworkReply::uploadProgress, this, &YggdrasilTask::refreshTimers); - connect(m_netReply, &QNetworkReply::downloadProgress, this, &YggdrasilTask::refreshTimers); - connect(m_netReply, &QNetworkReply::sslErrors, this, &YggdrasilTask::sslErrors); - timeout_keeper.setSingleShot(true); - timeout_keeper.start(timeout_max); - counter.setSingleShot(false); - counter.start(time_step); - progress(0, timeout_max); - connect(&timeout_keeper, &QTimer::timeout, this, &YggdrasilTask::abortByTimeout); - connect(&counter, &QTimer::timeout, this, &YggdrasilTask::heartbeat); -} - -void YggdrasilTask::refreshTimers(qint64, qint64) -{ - timeout_keeper.stop(); - timeout_keeper.start(timeout_max); - progress(count = 0, timeout_max); -} -void YggdrasilTask::heartbeat() -{ - count += time_step; - progress(count, timeout_max); -} - -bool YggdrasilTask::abort() -{ - progress(timeout_max, timeout_max); - // TODO: actually use this in a meaningful way - m_aborted = YggdrasilTask::BY_USER; - m_netReply->abort(); - return true; -} - -void YggdrasilTask::abortByTimeout() -{ - progress(timeout_max, timeout_max); - // TODO: actually use this in a meaningful way - m_aborted = YggdrasilTask::BY_TIMEOUT; - m_netReply->abort(); -} - -void YggdrasilTask::sslErrors(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 YggdrasilTask::processReply() -{ - changeState(STATE_PROCESSING_RESPONSE); - - switch (m_netReply->error()) - { - case QNetworkReply::NoError: - break; - case QNetworkReply::TimeoutError: - changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out.")); - return; - case QNetworkReply::OperationCanceledError: - changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled.")); - return; - case QNetworkReply::SslHandshakeFailedError: - changeState( - STATE_FAILED_SOFT, - tr("SSL Handshake failed.
There might be a few causes for it:
" - "
    " - "
  • You use Windows XP and need to update " - "your root certificates
  • " - "
  • Some device on your network is interfering with SSL traffic. In that case, " - "you have bigger worries than Minecraft not starting.
  • " - "
  • Possibly something else. Check the MultiMC log file for details
  • " - "
")); - return; - // used for invalid credentials and similar errors. Fall through. - case QNetworkReply::ContentOperationNotPermittedError: - break; - default: - changeState(STATE_FAILED_SOFT, - tr("Authentication operation failed due to a network error: %1 (%2)") - .arg(m_netReply->errorString()).arg(m_netReply->error())); - return; - } - - // Try to parse the response regardless of the response code. - // Sometimes the auth server will give more information and an error code. - QJsonParseError jsonError; - QByteArray replyData = m_netReply->readAll(); - QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError); - // Check the response code. - int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - if (responseCode == 200) - { - // If the response code was 200, then there shouldn't be an error. Make sure - // anyways. - // Also, sometimes an empty reply indicates success. If there was no data received, - // pass an empty json object to the processResponse function. - if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) - { - processResponse(replyData.size() > 0 ? doc.object() : QJsonObject()); - return; - } - else - { - changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response " - "JSON response: %1 at offset %2.") - .arg(jsonError.errorString()) - .arg(jsonError.offset)); - qCritical() << replyData; - } - return; - } - - // If the response code was not 200, then Yggdrasil may have given us information - // about the error. - // If we can parse the response, then get information from it. Otherwise just say - // there was an unknown error. - if (jsonError.error == QJsonParseError::NoError) - { - // We were able to parse the server's response. Woo! - // Call processError. If a subclass has overridden it then they'll handle their - // stuff there. - qDebug() << "The request failed, but the server gave us an error message. " - "Processing error."; - processError(doc.object()); - } - else - { - // The server didn't say anything regarding the error. Give the user an unknown - // error. - qDebug() - << "The request failed and the server gave no error message. Unknown error."; - changeState(STATE_FAILED_SOFT, - tr("An unknown error occurred when trying to communicate with the " - "authentication server: %1").arg(m_netReply->errorString())); - } -} - -void YggdrasilTask::processError(QJsonObject responseData) -{ - QJsonValue errorVal = responseData.value("error"); - QJsonValue errorMessageValue = responseData.value("errorMessage"); - QJsonValue causeVal = responseData.value("cause"); - - if (errorVal.isString() && errorMessageValue.isString()) - { - m_error = std::shared_ptr(new Error{ - errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")}); - changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose); - } - else - { - // Error is not in standard format. Don't set m_error and return unknown error. - changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred.")); - } -} - -QString YggdrasilTask::getStateMessage() const -{ - switch (m_state) - { - case STATE_CREATED: - return "Waiting..."; - case STATE_SENDING_REQUEST: - return tr("Sending request to auth servers..."); - case STATE_PROCESSING_RESPONSE: - return tr("Processing response from servers..."); - case STATE_SUCCEEDED: - return tr("Authentication task succeeded."); - case STATE_FAILED_SOFT: - return tr("Failed to contact the authentication server."); - case STATE_FAILED_HARD: - return tr("Failed to authenticate."); - default: - return tr("..."); - } -} - -void YggdrasilTask::changeState(YggdrasilTask::State newState, QString reason) -{ - m_state = newState; - setStatus(getStateMessage()); - if (newState == STATE_SUCCEEDED) - { - emitSucceeded(); - } - else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT) - { - emitFailed(reason); - } -} - -YggdrasilTask::State YggdrasilTask::state() -{ - return m_state; -} diff --git a/logic/auth/YggdrasilTask.h b/logic/auth/YggdrasilTask.h deleted file mode 100644 index d989bee3..00000000 --- a/logic/auth/YggdrasilTask.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include -#include -#include -#include - -#include "auth/MojangAccount.h" - -class QNetworkReply; - -/** - * A Yggdrasil task is a task that performs an operation on a given mojang account. - */ -class YggdrasilTask : public Task -{ - Q_OBJECT -public: - explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0); - - /** - * assign a session to this task. the session will be filled with required infomration - * upon completion - */ - void assignSession(AuthSessionPtr session) - { - m_session = session; - } - - /// get the assigned session for filling with information. - AuthSessionPtr getAssignedSession() - { - return m_session; - } - - /** - * Class describing a Yggdrasil error response. - */ - struct Error - { - QString m_errorMessageShort; - QString m_errorMessageVerbose; - QString m_cause; - }; - - enum AbortedBy - { - BY_NOTHING, - BY_USER, - BY_TIMEOUT - } m_aborted = BY_NOTHING; - - /** - * Enum for describing the state of the current task. - * Used by the getStateMessage function to determine what the status message should be. - */ - enum State - { - STATE_CREATED, - STATE_SENDING_REQUEST, - STATE_PROCESSING_RESPONSE, - STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated - STATE_FAILED_HARD, //!< hard failure. auth is invalid - STATE_SUCCEEDED - } m_state = STATE_CREATED; - -protected: - - virtual void executeTask() override; - - /** - * Gets the JSON object that will be sent to the authentication server. - * Should be overridden by subclasses. - */ - virtual QJsonObject getRequestContent() const = 0; - - /** - * Gets the endpoint to POST to. - * No leading slash. - */ - virtual QString getEndpoint() const = 0; - - /** - * Processes the response received from the server. - * If an error occurred, this should emit a failed signal and return false. - * If Yggdrasil gave an error response, it should call setError() first, and then return false. - * Otherwise, it should return true. - * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with - * an empty QJsonObject. - */ - virtual void processResponse(QJsonObject responseData) = 0; - - /** - * Processes an error response received from the server. - * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error. - * \returns a QString error message that will be passed to emitFailed. - */ - virtual void processError(QJsonObject responseData); - - /** - * Returns the state message for the given state. - * Used to set the status message for the task. - * Should be overridden by subclasses that want to change messages for a given state. - */ - virtual QString getStateMessage() const; - -protected -slots: - void processReply(); - void refreshTimers(qint64, qint64); - void heartbeat(); - void sslErrors(QList); - - void changeState(State newState, QString reason=QString()); -public -slots: - virtual bool abort() override; - void abortByTimeout(); - State state(); -protected: - // FIXME: segfault disaster waiting to happen - MojangAccount *m_account = nullptr; - QNetworkReply *m_netReply = nullptr; - std::shared_ptr m_error; - QTimer timeout_keeper; - QTimer counter; - int count = 0; // num msec since time reset - - const int timeout_max = 30000; - const int time_step = 50; - - AuthSessionPtr m_session; -}; diff --git a/logic/auth/flows/AuthenticateTask.cpp b/logic/auth/flows/AuthenticateTask.cpp deleted file mode 100644 index a609d28b..00000000 --- a/logic/auth/flows/AuthenticateTask.cpp +++ /dev/null @@ -1,203 +0,0 @@ - -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include - -AuthenticateTask::AuthenticateTask(MojangAccount * account, const QString &password, - QObject *parent) - : YggdrasilTask(account, parent), m_password(password) -{ -} - -QJsonObject AuthenticateTask::getRequestContent() const -{ - /* - * { - * "agent": { // optional - * "name": "Minecraft", // So far this is the only encountered value - * "version": 1 // This number might be increased - * // by the vanilla client in the future - * }, - * "username": "mojang account name", // Can be an email address or player name for - // unmigrated accounts - * "password": "mojang account password", - * "clientToken": "client identifier" // optional - * "requestUser": true/false // request the user structure - * } - */ - QJsonObject req; - - { - QJsonObject agent; - // C++ makes string literals void* for some stupid reason, so we have to tell it - // QString... Thanks Obama. - agent.insert("name", QString("Minecraft")); - agent.insert("version", 1); - req.insert("agent", agent); - } - - req.insert("username", m_account->username()); - req.insert("password", m_password); - req.insert("requestUser", true); - - // If we already have a client token, give it to the server. - // Otherwise, let the server give us one. - - if(m_account->m_clientToken.isEmpty()) - { - auto uuid = QUuid::createUuid(); - auto uuidString = uuid.toString().remove('{').remove('-').remove('}'); - m_account->m_clientToken = uuidString; - } - req.insert("clientToken", m_account->m_clientToken); - - return req; -} - -void AuthenticateTask::processResponse(QJsonObject responseData) -{ - // Read the response data. We need to get the client token, access token, and the selected - // profile. - qDebug() << "Processing authentication response."; - // qDebug() << responseData; - // If we already have a client token, make sure the one the server gave us matches our - // existing one. - qDebug() << "Getting client token."; - QString clientToken = responseData.value("clientToken").toString(""); - if (clientToken.isEmpty()) - { - // Fail if the server gave us an empty client token - changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token.")); - return; - } - if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken) - { - changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported.")); - return; - } - // Set the client token. - m_account->m_clientToken = clientToken; - - // Now, we set the access token. - qDebug() << "Getting access token."; - QString accessToken = responseData.value("accessToken").toString(""); - if (accessToken.isEmpty()) - { - // Fail if the server didn't give us an access token. - changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token.")); - return; - } - // Set the access token. - m_account->m_accessToken = accessToken; - - // Now we load the list of available profiles. - // Mojang hasn't yet implemented the profile system, - // but we might as well support what's there so we - // don't have trouble implementing it later. - qDebug() << "Loading profile list."; - QJsonArray availableProfiles = responseData.value("availableProfiles").toArray(); - QList loadedProfiles; - for (auto iter : availableProfiles) - { - QJsonObject profile = iter.toObject(); - // Profiles are easy, we just need their ID and name. - QString id = profile.value("id").toString(""); - QString name = profile.value("name").toString(""); - bool legacy = profile.value("legacy").toBool(false); - - if (id.isEmpty() || name.isEmpty()) - { - // This should never happen, but we might as well - // warn about it if it does so we can debug it easily. - // You never know when Mojang might do something truly derpy. - qWarning() << "Found entry in available profiles list with missing ID or name " - "field. Ignoring it."; - } - - // Now, add a new AccountProfile entry to the list. - loadedProfiles.append({id, name, legacy}); - } - // Put the list of profiles we loaded into the MojangAccount object. - m_account->m_profiles = loadedProfiles; - - // Finally, we set the current profile to the correct value. This is pretty simple. - // We do need to make sure that the current profile that the server gave us - // is actually in the available profiles list. - // If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know). - qDebug() << "Setting current profile."; - QJsonObject currentProfile = responseData.value("selectedProfile").toObject(); - QString currentProfileId = currentProfile.value("id").toString(""); - if (currentProfileId.isEmpty()) - { - changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify a currently selected profile. The account exists, but likely isn't premium.")); - return; - } - if (!m_account->setCurrentProfile(currentProfileId)) - { - changeState(STATE_FAILED_HARD, tr("Authentication server specified a selected profile that wasn't in the available profiles list.")); - return; - } - - // this is what the vanilla launcher passes to the userProperties launch param - if (responseData.contains("user")) - { - User u; - auto obj = responseData.value("user").toObject(); - u.id = obj.value("id").toString(); - auto propArray = obj.value("properties").toArray(); - for (auto prop : propArray) - { - auto propTuple = prop.toObject(); - auto name = propTuple.value("name").toString(); - auto value = propTuple.value("value").toString(); - u.properties.insert(name, value); - } - m_account->m_user = u; - } - - // We've made it through the minefield of possible errors. Return true to indicate that - // we've succeeded. - qDebug() << "Finished reading authentication response."; - changeState(STATE_SUCCEEDED); -} - -QString AuthenticateTask::getEndpoint() const -{ - return "authenticate"; -} - -QString AuthenticateTask::getStateMessage() const -{ - switch (m_state) - { - case STATE_SENDING_REQUEST: - return tr("Authenticating: Sending request..."); - case STATE_PROCESSING_RESPONSE: - return tr("Authenticating: Processing response..."); - default: - return YggdrasilTask::getStateMessage(); - } -} diff --git a/logic/auth/flows/AuthenticateTask.h b/logic/auth/flows/AuthenticateTask.h deleted file mode 100644 index 65975ae5..00000000 --- a/logic/auth/flows/AuthenticateTask.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include -#include -#include - -/** - * The authenticate task takes a MojangAccount with no access token and password and attempts to - * authenticate with Mojang's servers. - * If successful, it will set the MojangAccount's access token. - */ -class AuthenticateTask : public YggdrasilTask -{ - Q_OBJECT -public: - AuthenticateTask(MojangAccount *account, const QString &password, QObject *parent = 0); - -protected: - virtual QJsonObject getRequestContent() const override; - - virtual QString getEndpoint() const override; - - virtual void processResponse(QJsonObject responseData) override; - - virtual QString getStateMessage() const override; - -private: - QString m_password; -}; diff --git a/logic/auth/flows/RefreshTask.cpp b/logic/auth/flows/RefreshTask.cpp deleted file mode 100644 index 83511200..00000000 --- a/logic/auth/flows/RefreshTask.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include -#include -#include -#include - -#include - -RefreshTask::RefreshTask(MojangAccount *account) : YggdrasilTask(account) -{ -} - -QJsonObject RefreshTask::getRequestContent() const -{ - /* - * { - * "clientToken": "client identifier" - * "accessToken": "current access token to be refreshed" - * "selectedProfile": // specifying this causes errors - * { - * "id": "profile ID" - * "name": "profile name" - * } - * "requestUser": true/false // request the user structure - * } - */ - QJsonObject req; - req.insert("clientToken", m_account->m_clientToken); - req.insert("accessToken", m_account->m_accessToken); - /* - { - auto currentProfile = m_account->currentProfile(); - QJsonObject profile; - profile.insert("id", currentProfile->id()); - profile.insert("name", currentProfile->name()); - req.insert("selectedProfile", profile); - } - */ - req.insert("requestUser", true); - - return req; -} - -void RefreshTask::processResponse(QJsonObject responseData) -{ - // Read the response data. We need to get the client token, access token, and the selected - // profile. - qDebug() << "Processing authentication response."; - - // qDebug() << responseData; - // If we already have a client token, make sure the one the server gave us matches our - // existing one. - QString clientToken = responseData.value("clientToken").toString(""); - if (clientToken.isEmpty()) - { - // Fail if the server gave us an empty client token - changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token.")); - return; - } - if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken) - { - changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported.")); - return; - } - - // Now, we set the access token. - qDebug() << "Getting new access token."; - QString accessToken = responseData.value("accessToken").toString(""); - if (accessToken.isEmpty()) - { - // Fail if the server didn't give us an access token. - changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token.")); - return; - } - - // we validate that the server responded right. (our current profile = returned current - // profile) - QJsonObject currentProfile = responseData.value("selectedProfile").toObject(); - QString currentProfileId = currentProfile.value("id").toString(""); - if (m_account->currentProfile()->id != currentProfileId) - { - changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify the same prefile as expected.")); - return; - } - - // this is what the vanilla launcher passes to the userProperties launch param - if (responseData.contains("user")) - { - User u; - auto obj = responseData.value("user").toObject(); - u.id = obj.value("id").toString(); - auto propArray = obj.value("properties").toArray(); - for (auto prop : propArray) - { - auto propTuple = prop.toObject(); - auto name = propTuple.value("name").toString(); - auto value = propTuple.value("value").toString(); - u.properties.insert(name, value); - } - m_account->m_user = u; - } - - // We've made it through the minefield of possible errors. Return true to indicate that - // we've succeeded. - qDebug() << "Finished reading refresh response."; - // Reset the access token. - m_account->m_accessToken = accessToken; - changeState(STATE_SUCCEEDED); -} - -QString RefreshTask::getEndpoint() const -{ - return "refresh"; -} - -QString RefreshTask::getStateMessage() const -{ - switch (m_state) - { - case STATE_SENDING_REQUEST: - return tr("Refreshing login token..."); - case STATE_PROCESSING_RESPONSE: - return tr("Refreshing login token: Processing response..."); - default: - return YggdrasilTask::getStateMessage(); - } -} diff --git a/logic/auth/flows/RefreshTask.h b/logic/auth/flows/RefreshTask.h deleted file mode 100644 index 6894e963..00000000 --- a/logic/auth/flows/RefreshTask.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include -#include -#include - -/** - * The authenticate task takes a MojangAccount with a possibly timed-out access token - * and attempts to authenticate with Mojang's servers. - * If successful, it will set the new access token. The token is considered validated. - */ -class RefreshTask : public YggdrasilTask -{ - Q_OBJECT -public: - RefreshTask(MojangAccount * account); - -protected: - virtual QJsonObject getRequestContent() const override; - - virtual QString getEndpoint() const override; - - virtual void processResponse(QJsonObject responseData) override; - - virtual QString getStateMessage() const override; -}; - diff --git a/logic/auth/flows/ValidateTask.cpp b/logic/auth/flows/ValidateTask.cpp deleted file mode 100644 index 9a4dcd6d..00000000 --- a/logic/auth/flows/ValidateTask.cpp +++ /dev/null @@ -1,62 +0,0 @@ - -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include -#include -#include -#include - -#include - -ValidateTask::ValidateTask(MojangAccount * account, QObject *parent) - : YggdrasilTask(account, parent) -{ -} - -QJsonObject ValidateTask::getRequestContent() const -{ - QJsonObject req; - req.insert("accessToken", m_account->m_accessToken); - return req; -} - -void ValidateTask::processResponse(QJsonObject responseData) -{ - // Assume that if processError wasn't called, then the request was successful. - changeState(YggdrasilTask::STATE_SUCCEEDED); -} - -QString ValidateTask::getEndpoint() const -{ - return "validate"; -} - -QString ValidateTask::getStateMessage() const -{ - switch (m_state) - { - case YggdrasilTask::STATE_SENDING_REQUEST: - return tr("Validating access token: Sending request..."); - case YggdrasilTask::STATE_PROCESSING_RESPONSE: - return tr("Validating access token: Processing response..."); - default: - return YggdrasilTask::getStateMessage(); - } -} diff --git a/logic/auth/flows/ValidateTask.h b/logic/auth/flows/ValidateTask.h deleted file mode 100644 index 204596f9..00000000 --- a/logic/auth/flows/ValidateTask.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * :FIXME: DEAD CODE, DEAD CODE, DEAD CODE! :FIXME: - */ - -#pragma once - -#include - -#include -#include -#include - -/** - * The validate task takes a MojangAccount and checks to make sure its access token is valid. - */ -class ValidateTask : public YggdrasilTask -{ - Q_OBJECT -public: - ValidateTask(MojangAccount *account, QObject *parent = 0); - -protected: - virtual QJsonObject getRequestContent() const override; - - virtual QString getEndpoint() const override; - - virtual void processResponse(QJsonObject responseData) override; - - virtual QString getStateMessage() const override; - -private: -}; diff --git a/logic/forge/ForgeInstaller.cpp b/logic/forge/ForgeInstaller.cpp deleted file mode 100644 index 78acb8d4..00000000 --- a/logic/forge/ForgeInstaller.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ForgeInstaller.h" -#include "minecraft/MinecraftProfile.h" -#include "minecraft/GradleSpecifier.h" -#include "net/HttpMetaCache.h" -#include "tasks/Task.h" -#include "minecraft/OneSixInstance.h" -#include "forge/ForgeVersionList.h" -#include "minecraft/VersionFilterData.h" -#include "Env.h" -#include "Exception.h" -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -ForgeInstaller::ForgeInstaller() : BaseInstaller() -{ -} - -void ForgeInstaller::prepare(const QString &filename, const QString &universalUrl) -{ - std::shared_ptr newVersion; - m_universal_url = universalUrl; - - QuaZip zip(filename); - if (!zip.open(QuaZip::mdUnzip)) - return; - - QuaZipFile file(&zip); - - // read the install profile - if (!zip.setCurrentFile("install_profile.json")) - return; - - QJsonParseError jsonError; - if (!file.open(QIODevice::ReadOnly)) - return; - QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError); - file.close(); - if (jsonError.error != QJsonParseError::NoError) - return; - - if (!jsonDoc.isObject()) - return; - - QJsonObject root = jsonDoc.object(); - - auto installVal = root.value("install"); - auto versionInfoVal = root.value("versionInfo"); - if (!installVal.isObject() || !versionInfoVal.isObject()) - return; - - // read the forge version info - { - newVersion = MinecraftProfile::fromJson(versionInfoVal.toObject()); - if (!newVersion) - return; - } - - QJsonObject installObj = installVal.toObject(); - QString libraryName = installObj.value("path").toString(); - internalPath = installObj.value("filePath").toString(); - m_forgeVersionString = installObj.value("version").toString().remove("Forge").trimmed(); - - // where do we put the library? decode the mojang path - GradleSpecifier lib(libraryName); - - auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.toPath()); - finalPath = "libraries/" + lib.toPath(); - if (!FS::ensureFilePathExists(finalPath)) - return; - - if (!zip.setCurrentFile(internalPath)) - return; - if (!file.open(QIODevice::ReadOnly)) - return; - { - QByteArray data = file.readAll(); - // extract file - QSaveFile extraction(finalPath); - if (!extraction.open(QIODevice::WriteOnly)) - return; - if (extraction.write(data) != data.size()) - return; - if (!extraction.commit()) - return; - QCryptographicHash md5sum(QCryptographicHash::Md5); - md5sum.addData(data); - - cacheentry->stale = false; - cacheentry->md5sum = md5sum.result().toHex().constData(); - ENV.metacache()->updateEntry(cacheentry); - } - file.close(); - - m_forge_json = newVersion; - m_forge_json->id = installObj.value("minecraft").toString(); -} - -bool ForgeInstaller::add(OneSixInstance *to) -{ - if (!BaseInstaller::add(to)) - { - return false; - } - - QJsonObject obj; - obj.insert("order", 5); - - if (!m_forge_json) - return false; - int sliding_insert_window = 0; - { - QJsonArray librariesPlus; - // A blacklist - QSet blacklist{"authlib", "realms"}; - // - QList xzlist{"org.scala-lang", "com.typesafe"}; - // for each library in the version we are adding (except for the blacklisted) - for (auto lib : m_forge_json->libraries) - { - QString libName = lib->artifactId(); - QString rawName = lib->rawName(); - - // ignore lwjgl libraries. - if (g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) - continue; - // ignore other blacklisted (realms, authlib) - if (blacklist.contains(libName)) - continue; - - // WARNING: This could actually break. - // if this is the actual forge lib, set an absolute url for the download - if (m_forge_version->type == ForgeVersion::Gradle) - { - if (libName == "forge") - { - lib->setClassifier("universal"); - } - else if (libName == "minecraftforge") - { - QString forgeCoord("net.minecraftforge:forge:%1:universal"); - // using insane form of the MC version... - QString longVersion = - m_forge_version->mcver + "-" + m_forge_version->jobbuildver; - GradleSpecifier spec(forgeCoord.arg(longVersion)); - lib->setRawName(spec); - } - } - else - { - if (libName.contains("minecraftforge")) - { - lib->setAbsoluteUrl(m_universal_url); - } - } - - // WARNING: This could actually break. - // mark bad libraries based on the xzlist above - for (auto entry : xzlist) - { - qDebug() << "Testing " << rawName << " : " << entry; - if (rawName.startsWith(entry)) - { - lib->setHint("forge-pack-xz"); - break; - } - } - - QJsonObject libObj = lib->toJson(); - - bool found = false; - bool equals = false; - // find an entry that matches this one - for (auto tolib : to->getMinecraftProfile()->vanillaLibraries) - { - if (tolib->artifactId() != libName) - continue; - found = true; - if (tolib->toJson() == libObj) - { - equals = true; - } - // replace lib - libObj.insert("insert", QString("replace")); - break; - } - if (equals) - { - continue; - } - if (!found) - { - // add lib - libObj.insert("insert", QString("prepend")); - if (lib->artifactId() == "minecraftforge" || lib->artifactId() == "forge") - { - libObj.insert("MMC-depend", QString("hard")); - } - sliding_insert_window++; - } - librariesPlus.prepend(libObj); - } - obj.insert("+libraries", librariesPlus); - obj.insert("mainClass", m_forge_json->mainClass); - QString args = m_forge_json->minecraftArguments; - QStringList tweakers; - { - QRegularExpression expression("--tweakClass ([a-zA-Z0-9\\.]*)"); - QRegularExpressionMatch match = expression.match(args); - while (match.hasMatch()) - { - tweakers.append(match.captured(1)); - args.remove(match.capturedStart(), match.capturedLength()); - match = expression.match(args); - } - } - if (!args.isEmpty() && args != to->getMinecraftProfile()->vanillaMinecraftArguments) - { - obj.insert("minecraftArguments", args); - } - if (!tweakers.isEmpty()) - { - obj.insert("+tweakers", QJsonArray::fromStringList(tweakers)); - } - if (!m_forge_json->processArguments.isEmpty() && - m_forge_json->processArguments != to->getMinecraftProfile()->vanillaProcessArguments) - { - obj.insert("processArguments", m_forge_json->processArguments); - } - } - - obj.insert("name", QString("Forge")); - obj.insert("fileId", id()); - obj.insert("version", m_forgeVersionString); - obj.insert("mcVersion", to->intendedVersionId()); - - QFile file(filename(to->instanceRoot())); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); - return false; - } - file.write(QJsonDocument(obj).toJson()); - file.close(); - - return true; -} - -bool ForgeInstaller::addLegacy(OneSixInstance *to) -{ - if (!BaseInstaller::add(to)) - { - return false; - } - auto entry = ENV.metacache()->resolveEntry("minecraftforge", m_forge_version->filename()); - finalPath = FS::PathCombine(to->jarModsDir(), m_forge_version->filename()); - if (!FS::ensureFilePathExists(finalPath)) - { - return false; - } - if (!QFile::copy(entry->getFullPath(), finalPath)) - { - return false; - } - QJsonObject obj; - obj.insert("order", 5); - { - QJsonArray jarmodsPlus; - { - QJsonObject libObj; - libObj.insert("name", m_forge_version->universal_filename); - jarmodsPlus.append(libObj); - } - obj.insert("+jarMods", jarmodsPlus); - } - - obj.insert("name", QString("Forge")); - obj.insert("fileId", id()); - obj.insert("version", m_forge_version->jobbuildver); - obj.insert("mcVersion", to->intendedVersionId()); - if (g_VersionFilterData.fmlLibsMapping.contains(m_forge_version->mcver)) - { - QJsonArray traitsPlus; - traitsPlus.append(QString("legacyFML")); - obj.insert("+traits", traitsPlus); - } - auto fullversion = to->getMinecraftProfile(); - fullversion->remove("net.minecraftforge"); - - QFile file(filename(to->instanceRoot())); - if (!file.open(QFile::WriteOnly)) - { - qCritical() << "Error opening" << file.fileName() - << "for reading:" << file.errorString(); - return false; - } - file.write(QJsonDocument(obj).toJson()); - file.close(); - return true; -} - -class ForgeInstallTask : public Task -{ - Q_OBJECT -public: - ForgeInstallTask(ForgeInstaller *installer, OneSixInstance *instance, - BaseVersionPtr version, QObject *parent = 0) - : Task(parent), m_installer(installer), m_instance(instance), m_version(version) - { - } - -protected: - void executeTask() override - { - setStatus(tr("Installing Forge...")); - ForgeVersionPtr forgeVersion = std::dynamic_pointer_cast(m_version); - if (!forgeVersion) - { - emitFailed(tr("Unknown error occured")); - return; - } - prepare(forgeVersion); - } - void prepare(ForgeVersionPtr forgeVersion) - { - auto entry = ENV.metacache()->resolveEntry("minecraftforge", forgeVersion->filename()); - auto installFunction = [this, entry, forgeVersion]() - { - if (!install(entry, forgeVersion)) - { - qCritical() << "Failure installing Forge"; - emitFailed(tr("Failure to install Forge")); - } - else - { - reload(); - } - }; - - /* - * HACK IF the local non-stale file is too small, mark is as stale - * - * This fixes some problems with bad files acquired because of unhandled HTTP redirects - * in old versions of MultiMC. - */ - if (!entry->stale) - { - QFileInfo localFile(entry->getFullPath()); - if (localFile.size() <= 0x4000) - { - entry->stale = true; - } - } - - if (entry->stale) - { - NetJob *fjob = new NetJob("Forge download"); - fjob->addNetAction(CacheDownload::make(forgeVersion->url(), entry)); - connect(fjob, &NetJob::progress, this, &Task::setProgress); - connect(fjob, &NetJob::status, this, &Task::setStatus); - connect(fjob, &NetJob::failed, [this](QString reason) - { emitFailed(tr("Failure to download Forge:\n%1").arg(reason)); }); - connect(fjob, &NetJob::succeeded, installFunction); - fjob->start(); - } - else - { - installFunction(); - } - } - bool install(const std::shared_ptr &entry, const ForgeVersionPtr &forgeVersion) - { - if (forgeVersion->usesInstaller()) - { - QString forgePath = entry->getFullPath(); - m_installer->prepare(forgePath, forgeVersion->universal_url); - return m_installer->add(m_instance); - } - else - return m_installer->addLegacy(m_instance); - } - void reload() - { - try - { - m_instance->reloadProfile(); - emitSucceeded(); - } - catch (Exception &e) - { - emitFailed(e.cause()); - } - catch (...) - { - emitFailed(tr("Failed to load the version description file for reasons unknown.")); - } - } - -private: - ForgeInstaller *m_installer; - OneSixInstance *m_instance; - BaseVersionPtr m_version; -}; - -Task *ForgeInstaller::createInstallTask(OneSixInstance *instance, - BaseVersionPtr version, QObject *parent) -{ - if (!version) - { - return nullptr; - } - m_forge_version = std::dynamic_pointer_cast(version); - return new ForgeInstallTask(this, instance, version, parent); -} - -#include "ForgeInstaller.moc" diff --git a/logic/forge/ForgeInstaller.h b/logic/forge/ForgeInstaller.h deleted file mode 100644 index 0de762b6..00000000 --- a/logic/forge/ForgeInstaller.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "BaseInstaller.h" - -#include -#include - -#include "multimc_logic_export.h" - -class MinecraftProfile; -class ForgeInstallTask; -struct ForgeVersion; - -class MULTIMC_LOGIC_EXPORT ForgeInstaller : public BaseInstaller -{ - friend class ForgeInstallTask; -public: - ForgeInstaller(); - virtual ~ForgeInstaller(){} - virtual Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override; - virtual QString id() const override { return "net.minecraftforge"; } - -protected: - void prepare(const QString &filename, const QString &universalUrl); - bool add(OneSixInstance *to) override; - bool addLegacy(OneSixInstance *to); - -private: - // the parsed version json, read from the installer - std::shared_ptr m_forge_json; - // the actual forge version - std::shared_ptr m_forge_version; - QString internalPath; - QString finalPath; - QString m_forgeVersionString; - QString m_universal_url; -}; diff --git a/logic/forge/ForgeMirror.h b/logic/forge/ForgeMirror.h deleted file mode 100644 index 2518dffe..00000000 --- a/logic/forge/ForgeMirror.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -struct ForgeMirror -{ - QString name; - QString logo_url; - QString website_url; - QString mirror_url; -}; \ No newline at end of file diff --git a/logic/forge/ForgeMirrors.cpp b/logic/forge/ForgeMirrors.cpp deleted file mode 100644 index a2fc2c62..00000000 --- a/logic/forge/ForgeMirrors.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "Env.h" -#include "ForgeMirrors.h" -#include -#include -#include - -ForgeMirrors::ForgeMirrors(QList &libs, NetJobPtr parent_job, - QString mirrorlist) -{ - m_libs = libs; - m_parent_job = parent_job; - m_url = QUrl(mirrorlist); - m_status = Job_NotStarted; -} - -void ForgeMirrors::start() -{ - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - auto worker = ENV.qnam(); - QNetworkReply *rep = worker->get(request); - - m_reply.reset(rep); - connect(rep, SIGNAL(downloadProgress(qint64, qint64)), - SLOT(downloadProgress(qint64, qint64))); - connect(rep, SIGNAL(finished()), SLOT(downloadFinished())); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), - SLOT(downloadError(QNetworkReply::NetworkError))); - connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead())); -} - -void ForgeMirrors::downloadError(QNetworkReply::NetworkError error) -{ - // error happened during download. - qCritical() << "Error getting URL:" << m_url.toString().toLocal8Bit() - << "Network error: " << error; - m_status = Job_Failed; -} - -void ForgeMirrors::downloadFinished() -{ - // if the download succeeded - if (m_status != Job_Failed) - { - // nothing went wrong... ? - parseMirrorList(); - return; - } - // else the download failed, we use a fixed list - else - { - m_status = Job_Finished; - m_reply.reset(); - deferToFixedList(); - return; - } -} - -void ForgeMirrors::deferToFixedList() -{ - m_mirrors.clear(); - m_mirrors.append( - {"Minecraft Forge", "http://files.minecraftforge.net/forge_logo.png", - "http://files.minecraftforge.net/", "http://files.minecraftforge.net/maven/"}); - m_mirrors.append({"Creeper Host", - "http://files.minecraftforge.net/forge_logo.png", - "https://www.creeperhost.net/link.php?id=1", - "http://new.creeperrepo.net/forge/maven/"}); - injectDownloads(); - emit succeeded(m_index_within_job); -} - -void ForgeMirrors::parseMirrorList() -{ - m_status = Job_Finished; - auto data = m_reply->readAll(); - m_reply.reset(); - auto dataLines = data.split('\n'); - for(auto line: dataLines) - { - auto elements = line.split('!'); - if (elements.size() == 4) - { - m_mirrors.append({elements[0],elements[1],elements[2],elements[3]}); - } - } - if(!m_mirrors.size()) - deferToFixedList(); - injectDownloads(); - emit succeeded(m_index_within_job); -} - -void ForgeMirrors::injectDownloads() -{ - // shuffle the mirrors randomly - std::random_device rd; - std::mt19937 rng(rd()); - std::shuffle(m_mirrors.begin(), m_mirrors.end(), rng); - - // tell parent to download the libs - for(auto lib: m_libs) - { - lib->setMirrors(m_mirrors); - m_parent_job->addNetAction(lib); - } -} - -void ForgeMirrors::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void ForgeMirrors::downloadReadyRead() -{ -} diff --git a/logic/forge/ForgeMirrors.h b/logic/forge/ForgeMirrors.h deleted file mode 100644 index e7c90fa5..00000000 --- a/logic/forge/ForgeMirrors.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "net/NetAction.h" -#include "net/HttpMetaCache.h" -#include "net/NetJob.h" -#include "forge/ForgeXzDownload.h" -#include -#include -typedef std::shared_ptr ForgeMirrorsPtr; - -class ForgeMirrors : public NetAction -{ - Q_OBJECT -public: - QList m_libs; - NetJobPtr m_parent_job; - QList m_mirrors; - -public: - explicit ForgeMirrors(QList &libs, NetJobPtr parent_job, - QString mirrorlist); - static ForgeMirrorsPtr make(QList &libs, NetJobPtr parent_job, - QString mirrorlist) - { - return ForgeMirrorsPtr(new ForgeMirrors(libs, parent_job, mirrorlist)); - } - virtual ~ForgeMirrors(){}; -protected -slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead(); - -private: - void parseMirrorList(); - void deferToFixedList(); - void injectDownloads(); - -public -slots: - virtual void start(); -}; diff --git a/logic/forge/ForgeVersion.cpp b/logic/forge/ForgeVersion.cpp deleted file mode 100644 index b859a28c..00000000 --- a/logic/forge/ForgeVersion.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ForgeVersion.h" -#include "minecraft/VersionFilterData.h" -#include - -QString ForgeVersion::name() -{ - return "Forge " + jobbuildver; -} - -QString ForgeVersion::descriptor() -{ - return universal_filename; -} - -QString ForgeVersion::typeString() const -{ - if (is_recommended) - return QObject::tr("Recommended"); - return QString(); -} - -bool ForgeVersion::operator<(BaseVersion &a) -{ - ForgeVersion *pa = dynamic_cast(&a); - if (!pa) - return true; - return m_buildnr < pa->m_buildnr; -} - -bool ForgeVersion::operator>(BaseVersion &a) -{ - ForgeVersion *pa = dynamic_cast(&a); - if (!pa) - return false; - return m_buildnr > pa->m_buildnr; -} - -bool ForgeVersion::usesInstaller() -{ - if(installer_url.isEmpty()) - return false; - if(g_VersionFilterData.forgeInstallerBlacklist.contains(mcver)) - return false; - return true; -} - -QString ForgeVersion::filename() -{ - return usesInstaller() ? installer_filename : universal_filename; -} - -QString ForgeVersion::url() -{ - return usesInstaller() ? installer_url : universal_url; -} diff --git a/logic/forge/ForgeVersion.h b/logic/forge/ForgeVersion.h deleted file mode 100644 index e77d32f1..00000000 --- a/logic/forge/ForgeVersion.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include -#include -#include "BaseVersion.h" - -struct ForgeVersion; -typedef std::shared_ptr ForgeVersionPtr; - -struct ForgeVersion : public BaseVersion -{ - virtual QString descriptor() override; - virtual QString name() override; - virtual QString typeString() const override; - virtual bool operator<(BaseVersion &a) override; - virtual bool operator>(BaseVersion &a) override; - - QString filename(); - QString url(); - - enum - { - Invalid, - Legacy, - Gradle - } type = Invalid; - - bool usesInstaller(); - - int m_buildnr = 0; - QString branch; - QString universal_url; - QString changelog_url; - QString installer_url; - QString jobbuildver; - QString mcver; - QString mcver_sane; - QString universal_filename; - QString installer_filename; - bool is_recommended = false; -}; - -Q_DECLARE_METATYPE(ForgeVersionPtr) diff --git a/logic/forge/ForgeVersionList.cpp b/logic/forge/ForgeVersionList.cpp deleted file mode 100644 index a05ced99..00000000 --- a/logic/forge/ForgeVersionList.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "forge/ForgeVersionList.h" -#include "forge/ForgeVersion.h" -#include "net/NetJob.h" -#include "net/URLConstants.h" -#include "Env.h" - -#include -#include -#include - -#include - -ForgeVersionList::ForgeVersionList(QObject *parent) : BaseVersionList(parent) -{ -} - -Task *ForgeVersionList::getLoadTask() -{ - return new ForgeListLoadTask(this); -} - -bool ForgeVersionList::isLoaded() -{ - return m_loaded; -} - -const BaseVersionPtr ForgeVersionList::at(int i) const -{ - return m_vlist.at(i); -} - -int ForgeVersionList::count() const -{ - return m_vlist.count(); -} - -int ForgeVersionList::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -QVariant ForgeVersionList::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() > count()) - return QVariant(); - - auto version = std::dynamic_pointer_cast(m_vlist[index.row()]); - switch (role) - { - case VersionPointerRole: - return qVariantFromValue(m_vlist[index.row()]); - - case VersionRole: - return version->name(); - - case VersionIdRole: - return version->descriptor(); - - case ParentGameVersionRole: - return version->mcver_sane; - - case RecommendedRole: - return version->is_recommended; - - case BranchRole: - return version->branch; - - default: - return QVariant(); - } -} - -QList ForgeVersionList::providesRoles() -{ - return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole, BranchRole}; -} - -BaseVersionPtr ForgeVersionList::getLatestStable() const -{ - return BaseVersionPtr(); -} - -void ForgeVersionList::updateListData(QList versions) -{ - beginResetModel(); - m_vlist = versions; - m_loaded = true; - endResetModel(); - // NOW SORT!! - // sort(); -} - -void ForgeVersionList::sortVersions() -{ - // NO-OP for now -} - -ForgeListLoadTask::ForgeListLoadTask(ForgeVersionList *vlist) : Task() -{ - m_list = vlist; -} - -void ForgeListLoadTask::executeTask() -{ - setStatus(tr("Fetching Forge version lists...")); - auto job = new NetJob("Version index"); - // we do not care if the version is stale or not. - auto forgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "list.json"); - auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json"); - - // verify by poking the server. - forgeListEntry->stale = true; - gradleForgeListEntry->stale = true; - - job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL), - forgeListEntry)); - job->addNetAction(gradleListDownload = CacheDownload::make( - QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry)); - - connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed())); - connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed())); - - listJob.reset(job); - connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded())); - connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); - listJob->start(); -} - -bool ForgeListLoadTask::abort() -{ - return listJob->abort(); -} - -bool ForgeListLoadTask::parseForgeList(QList &out) -{ - QByteArray data; - { - auto dlJob = listDownload; - auto filename = std::dynamic_pointer_cast(dlJob)->getTargetFilepath(); - QFile listFile(filename); - if (!listFile.open(QIODevice::ReadOnly)) - { - return false; - } - data = listFile.readAll(); - dlJob.reset(); - } - - QJsonParseError jsonError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); - - if (jsonError.error != QJsonParseError::NoError) - { - emitFailed("Error parsing version list JSON:" + jsonError.errorString()); - return false; - } - - if (!jsonDoc.isObject()) - { - emitFailed("Error parsing version list JSON: JSON root is not an object"); - return false; - } - - QJsonObject root = jsonDoc.object(); - - // Now, get the array of versions. - if (!root.value("builds").isArray()) - { - emitFailed( - "Error parsing version list JSON: version list object is missing 'builds' array"); - return false; - } - QJsonArray builds = root.value("builds").toArray(); - - for (int i = 0; i < builds.count(); i++) - { - // Load the version info. - if (!builds[i].isObject()) - { - // FIXME: log this somewhere - continue; - } - QJsonObject obj = builds[i].toObject(); - int build_nr = obj.value("build").toDouble(0); - if (!build_nr) - continue; - QJsonArray files = obj.value("files").toArray(); - QString url, jobbuildver, mcver, buildtype, universal_filename; - QString changelog_url, installer_url; - QString installer_filename; - bool valid = false; - for (int j = 0; j < files.count(); j++) - { - if (!files[j].isObject()) - { - continue; - } - QJsonObject file = files[j].toObject(); - buildtype = file.value("buildtype").toString(); - if ((buildtype == "client" || buildtype == "universal") && !valid) - { - mcver = file.value("mcver").toString(); - url = file.value("url").toString(); - jobbuildver = file.value("jobbuildver").toString(); - int lastSlash = url.lastIndexOf('/'); - universal_filename = url.mid(lastSlash + 1); - valid = true; - } - else if (buildtype == "changelog") - { - QString ext = file.value("ext").toString(); - if (ext.isEmpty()) - { - continue; - } - changelog_url = file.value("url").toString(); - } - else if (buildtype == "installer") - { - installer_url = file.value("url").toString(); - int lastSlash = installer_url.lastIndexOf('/'); - installer_filename = installer_url.mid(lastSlash + 1); - } - } - if (valid) - { - // Now, we construct the version object and add it to the list. - std::shared_ptr fVersion(new ForgeVersion()); - fVersion->universal_url = url; - fVersion->changelog_url = changelog_url; - fVersion->installer_url = installer_url; - fVersion->jobbuildver = jobbuildver; - fVersion->mcver = fVersion->mcver_sane = mcver; - fVersion->installer_filename = installer_filename; - fVersion->universal_filename = universal_filename; - fVersion->m_buildnr = build_nr; - fVersion->type = ForgeVersion::Legacy; - out.append(fVersion); - } - } - - return true; -} - -bool ForgeListLoadTask::parseForgeGradleList(QList &out) -{ - QMap> lookup; - QByteArray data; - { - auto dlJob = gradleListDownload; - auto filename = std::dynamic_pointer_cast(dlJob)->getTargetFilepath(); - QFile listFile(filename); - if (!listFile.open(QIODevice::ReadOnly)) - { - return false; - } - data = listFile.readAll(); - dlJob.reset(); - } - - QJsonParseError jsonError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); - - if (jsonError.error != QJsonParseError::NoError) - { - emitFailed("Error parsing gradle version list JSON:" + jsonError.errorString()); - return false; - } - - if (!jsonDoc.isObject()) - { - emitFailed("Error parsing gradle version list JSON: JSON root is not an object"); - return false; - } - - QJsonObject root = jsonDoc.object(); - - // we probably could hard code these, but it might still be worth doing it this way - const QString webpath = root.value("webpath").toString(); - const QString artifact = root.value("artifact").toString(); - - QJsonObject numbers = root.value("number").toObject(); - for (auto it = numbers.begin(); it != numbers.end(); ++it) - { - QJsonObject number = it.value().toObject(); - std::shared_ptr fVersion(new ForgeVersion()); - fVersion->m_buildnr = number.value("build").toDouble(); - if(fVersion->m_buildnr >= 953 && fVersion->m_buildnr <= 965) - { - qDebug() << fVersion->m_buildnr; - } - fVersion->jobbuildver = number.value("version").toString(); - fVersion->branch = number.value("branch").toString(""); - fVersion->mcver = number.value("mcversion").toString(); - fVersion->universal_filename = ""; - fVersion->installer_filename = ""; - // HACK: here, we fix the minecraft version used by forge. - // HACK: this will inevitably break (later) - // FIXME: replace with a dictionary - fVersion->mcver_sane = fVersion->mcver; - fVersion->mcver_sane.replace("_pre", "-pre"); - - QString universal_filename, installer_filename; - QJsonArray files = number.value("files").toArray(); - for (auto fIt = files.begin(); fIt != files.end(); ++fIt) - { - // TODO with gradle we also get checksums, use them - QJsonArray file = (*fIt).toArray(); - if (file.size() < 3) - { - continue; - } - - QString extension = file.at(0).toString(); - QString part = file.at(1).toString(); - QString checksum = file.at(2).toString(); - - // insane form of mcver is used here - QString longVersion = fVersion->mcver + "-" + fVersion->jobbuildver; - if (!fVersion->branch.isEmpty()) - { - longVersion = longVersion + "-" + fVersion->branch; - } - QString filename = artifact + "-" + longVersion + "-" + part + "." + extension; - - QString url = QString("%1/%2/%3") - .arg(webpath) - .arg(longVersion) - .arg(filename); - - if (part == "installer") - { - fVersion->installer_url = url; - installer_filename = filename; - } - else if (part == "universal") - { - fVersion->universal_url = url; - universal_filename = filename; - } - else if (part == "changelog") - { - fVersion->changelog_url = url; - } - } - if (fVersion->installer_url.isEmpty() && fVersion->universal_url.isEmpty()) - { - continue; - } - fVersion->universal_filename = universal_filename; - fVersion->installer_filename = installer_filename; - fVersion->type = ForgeVersion::Gradle; - out.append(fVersion); - lookup[fVersion->m_buildnr] = fVersion; - } - QJsonObject promos = root.value("promos").toObject(); - for (auto it = promos.begin(); it != promos.end(); ++it) - { - QString key = it.key(); - int build = it.value().toInt(); - QRegularExpression regexp("^(?[0-9]+(.[0-9]+)*)-(?