diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | doc/multimc.1.txt | 2 | ||||
-rw-r--r-- | launcher/Application.cpp (renamed from launcher/Launcher.cpp) | 328 | ||||
-rw-r--r-- | launcher/Application.h (renamed from launcher/Launcher.h) | 99 | ||||
-rw-r--r-- | launcher/ApplicationMessage.cpp (renamed from launcher/LauncherMessage.cpp) | 6 | ||||
-rw-r--r-- | launcher/ApplicationMessage.h (renamed from launcher/LauncherMessage.h) | 2 | ||||
-rw-r--r-- | launcher/BaseInstance.h | 2 | ||||
-rw-r--r-- | launcher/BaseVersionList.h | 2 | ||||
-rw-r--r-- | launcher/CMakeLists.txt | 529 | ||||
-rw-r--r-- | launcher/ColumnResizer.cpp | 199 | ||||
-rw-r--r-- | launcher/ColumnResizer.h | 41 | ||||
-rw-r--r-- | launcher/Env.cpp | 210 | ||||
-rw-r--r-- | launcher/Env.h | 63 | ||||
-rw-r--r-- | launcher/InstanceImportTask.cpp | 17 | ||||
-rw-r--r-- | launcher/InstanceImportTask.h | 2 | ||||
-rw-r--r-- | launcher/InstancePageProvider.h | 34 | ||||
-rw-r--r-- | launcher/JavaCommon.cpp | 2 | ||||
-rw-r--r-- | launcher/LaunchController.cpp | 80 | ||||
-rw-r--r-- | launcher/QObjectPtr.h | 6 | ||||
-rw-r--r-- | launcher/SkinUtils.cpp | 4 | ||||
-rw-r--r-- | launcher/Usable.h | 10 | ||||
-rw-r--r-- | launcher/VersionProxyModel.cpp | 8 | ||||
-rw-r--r-- | launcher/icons/IIconList.cpp | 7 | ||||
-rw-r--r-- | launcher/icons/IIconList.h | 25 | ||||
-rw-r--r-- | launcher/icons/IconList.h | 23 | ||||
-rw-r--r-- | launcher/icons/MMCIcon.h | 10 | ||||
-rw-r--r-- | launcher/java/JavaChecker.cpp | 12 | ||||
-rw-r--r-- | launcher/java/JavaInstallList.cpp | 4 | ||||
-rw-r--r-- | launcher/java/JavaInstallList.h | 4 | ||||
-rw-r--r-- | launcher/java/JavaUtils.cpp | 18 | ||||
-rw-r--r-- | launcher/launch/steps/CheckJava.cpp (renamed from launcher/java/launch/CheckJava.cpp) | 0 | ||||
-rw-r--r-- | launcher/launch/steps/CheckJava.h (renamed from launcher/java/launch/CheckJava.h) | 0 | ||||
-rw-r--r-- | launcher/launch/steps/Update.h | 2 | ||||
-rw-r--r-- | launcher/main.cpp | 16 | ||||
-rw-r--r-- | launcher/meta/BaseEntity.cpp | 20 | ||||
-rw-r--r-- | launcher/meta/BaseEntity.h | 6 | ||||
-rw-r--r-- | launcher/meta/Index_test.cpp | 7 | ||||
-rw-r--r-- | launcher/meta/VersionList.cpp | 2 | ||||
-rw-r--r-- | launcher/meta/VersionList.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/AssetsUtils.cpp | 4 | ||||
-rw-r--r-- | launcher/minecraft/AssetsUtils.h | 4 | ||||
-rw-r--r-- | launcher/minecraft/Component.cpp | 18 | ||||
-rw-r--r-- | launcher/minecraft/ComponentUpdateTask.cpp | 33 | ||||
-rw-r--r-- | launcher/minecraft/Library.cpp | 5 | ||||
-rw-r--r-- | launcher/minecraft/Library.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/Library_test.cpp | 2 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftInstance.cpp | 44 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftInstance.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftLoadAndCheck.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftUpdate.cpp | 1 | ||||
-rw-r--r-- | launcher/minecraft/PackProfile.cpp | 23 | ||||
-rw-r--r-- | launcher/minecraft/PackProfile.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/PackProfile_p.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/VersionFilterData.cpp | 1 | ||||
-rw-r--r-- | launcher/minecraft/VersionFilterData.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/auth/AccountData.cpp | 45 | ||||
-rw-r--r-- | launcher/minecraft/auth/AccountData.h | 7 | ||||
-rw-r--r-- | launcher/minecraft/auth/AccountList.cpp | 167 | ||||
-rw-r--r-- | launcher/minecraft/auth/AccountList.h | 21 | ||||
-rw-r--r-- | launcher/minecraft/auth/AccountTask.cpp | 4 | ||||
-rw-r--r-- | launcher/minecraft/auth/AuthSession.h | 4 | ||||
-rw-r--r-- | launcher/minecraft/auth/MinecraftAccount.cpp | 99 | ||||
-rw-r--r-- | launcher/minecraft/auth/MinecraftAccount.h | 29 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/AuthContext.cpp | 466 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/AuthContext.h | 13 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/AuthRequest.cpp | 6 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/AuthRequest.h | 1 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MSAInteractive.cpp | 8 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MSAInteractive.h | 5 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MSASilent.h | 5 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MojangLogin.cpp | 6 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MojangLogin.h | 6 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MojangRefresh.cpp | 5 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/MojangRefresh.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/Parsers.cpp | 316 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/Parsers.h | 19 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/Yggdrasil.cpp | 72 | ||||
-rw-r--r-- | launcher/minecraft/auth/flows/Yggdrasil.h | 6 | ||||
-rw-r--r-- | launcher/minecraft/launch/ClaimAccount.cpp | 6 | ||||
-rw-r--r-- | launcher/minecraft/launch/LauncherPartLaunch.cpp | 15 | ||||
-rw-r--r-- | launcher/minecraft/launch/VerifyJavaInstall.cpp | 11 | ||||
-rw-r--r-- | launcher/minecraft/legacy/LegacyInstance.cpp | 2 | ||||
-rw-r--r-- | launcher/minecraft/legacy/LegacyInstance.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/services/CapeChange.cpp | 12 | ||||
-rw-r--r-- | launcher/minecraft/services/CapeChange.h | 3 | ||||
-rw-r--r-- | launcher/minecraft/services/SkinDelete.cpp | 8 | ||||
-rw-r--r-- | launcher/minecraft/services/SkinDelete.h | 5 | ||||
-rw-r--r-- | launcher/minecraft/services/SkinUpload.cpp | 8 | ||||
-rw-r--r-- | launcher/minecraft/services/SkinUpload.h | 4 | ||||
-rw-r--r-- | launcher/minecraft/update/AssetUpdateTask.cpp | 12 | ||||
-rw-r--r-- | launcher/minecraft/update/AssetUpdateTask.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/update/FMLLibrariesTask.cpp | 14 | ||||
-rw-r--r-- | launcher/minecraft/update/FMLLibrariesTask.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/update/LibrariesTask.cpp | 8 | ||||
-rw-r--r-- | launcher/minecraft/update/LibrariesTask.h | 2 | ||||
-rw-r--r-- | launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 39 | ||||
-rw-r--r-- | launcher/modplatform/atlauncher/ATLPackInstallTask.h | 2 | ||||
-rw-r--r-- | launcher/modplatform/flame/FileResolvingTask.cpp | 8 | ||||
-rw-r--r-- | launcher/modplatform/flame/FileResolvingTask.h | 5 | ||||
-rw-r--r-- | launcher/modplatform/legacy_ftb/PackFetchTask.cpp | 18 | ||||
-rw-r--r-- | launcher/modplatform/legacy_ftb/PackFetchTask.h | 5 | ||||
-rw-r--r-- | launcher/modplatform/legacy_ftb/PackInstallTask.cpp | 26 | ||||
-rw-r--r-- | launcher/modplatform/legacy_ftb/PackInstallTask.h | 7 | ||||
-rw-r--r-- | launcher/modplatform/modpacksch/FTBPackInstallTask.cpp | 13 | ||||
-rw-r--r-- | launcher/modplatform/modpacksch/FTBPackInstallTask.h | 2 | ||||
-rw-r--r-- | launcher/modplatform/technic/SingleZipPackInstallTask.cpp | 11 | ||||
-rw-r--r-- | launcher/modplatform/technic/SingleZipPackInstallTask.h | 2 | ||||
-rw-r--r-- | launcher/modplatform/technic/SolderPackInstallTask.cpp | 14 | ||||
-rw-r--r-- | launcher/modplatform/technic/SolderPackInstallTask.h | 6 | ||||
-rw-r--r-- | launcher/net/Download.cpp | 19 | ||||
-rw-r--r-- | launcher/net/Download.h | 6 | ||||
-rw-r--r-- | launcher/net/FileSink.cpp | 1 | ||||
-rw-r--r-- | launcher/net/HttpMetaCache.cpp | 1 | ||||
-rw-r--r-- | launcher/net/MetaCacheSink.cpp | 4 | ||||
-rw-r--r-- | launcher/net/NetAction.h | 15 | ||||
-rw-r--r-- | launcher/net/NetJob.cpp | 4 | ||||
-rw-r--r-- | launcher/net/NetJob.h | 30 | ||||
-rw-r--r-- | launcher/net/PasteUpload.cpp | 7 | ||||
-rw-r--r-- | launcher/news/NewsChecker.cpp | 5 | ||||
-rw-r--r-- | launcher/news/NewsChecker.h | 6 | ||||
-rw-r--r-- | launcher/notifications/NotificationChecker.cpp | 6 | ||||
-rw-r--r-- | launcher/notifications/NotificationChecker.h | 2 | ||||
-rw-r--r-- | launcher/package/ubuntu/multimc/usr/share/man/man1/multimc.1 | 11 | ||||
-rw-r--r-- | launcher/screenshots/ImgurAlbumCreation.cpp | 10 | ||||
-rw-r--r-- | launcher/screenshots/ImgurAlbumCreation.h | 11 | ||||
-rw-r--r-- | launcher/screenshots/ImgurUpload.cpp | 10 | ||||
-rw-r--r-- | launcher/screenshots/ImgurUpload.h | 28 | ||||
-rw-r--r-- | launcher/screenshots/Screenshot.h | 10 | ||||
-rw-r--r-- | launcher/tasks/SequentialTask.cpp | 6 | ||||
-rw-r--r-- | launcher/tasks/SequentialTask.h | 6 | ||||
-rw-r--r-- | launcher/tasks/Task.h | 4 | ||||
-rw-r--r-- | launcher/translations/TranslationsModel.cpp | 26 | ||||
-rw-r--r-- | launcher/ui/ColorCache.cpp (renamed from launcher/ColorCache.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/ColorCache.h (renamed from launcher/ColorCache.h) | 0 | ||||
-rw-r--r-- | launcher/ui/GuiUtil.cpp (renamed from launcher/GuiUtil.cpp) | 19 | ||||
-rw-r--r-- | launcher/ui/GuiUtil.h (renamed from launcher/GuiUtil.h) | 0 | ||||
-rw-r--r-- | launcher/ui/InstanceWindow.cpp (renamed from launcher/InstanceWindow.cpp) | 25 | ||||
-rw-r--r-- | launcher/ui/InstanceWindow.h (renamed from launcher/InstanceWindow.h) | 9 | ||||
-rw-r--r-- | launcher/ui/MainWindow.cpp (renamed from launcher/MainWindow.cpp) | 308 | ||||
-rw-r--r-- | launcher/ui/MainWindow.h (renamed from launcher/MainWindow.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/AboutDialog.cpp (renamed from launcher/dialogs/AboutDialog.cpp) | 8 | ||||
-rw-r--r-- | launcher/ui/dialogs/AboutDialog.h (renamed from launcher/dialogs/AboutDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/AboutDialog.ui (renamed from launcher/dialogs/AboutDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/CopyInstanceDialog.cpp (renamed from launcher/dialogs/CopyInstanceDialog.cpp) | 12 | ||||
-rw-r--r-- | launcher/ui/dialogs/CopyInstanceDialog.h (renamed from launcher/dialogs/CopyInstanceDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/CopyInstanceDialog.ui (renamed from launcher/dialogs/CopyInstanceDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/CustomMessageBox.cpp (renamed from launcher/dialogs/CustomMessageBox.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/CustomMessageBox.h (renamed from launcher/dialogs/CustomMessageBox.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/EditAccountDialog.cpp (renamed from launcher/dialogs/EditAccountDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/EditAccountDialog.h (renamed from launcher/dialogs/EditAccountDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/EditAccountDialog.ui (renamed from launcher/dialogs/EditAccountDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ExportInstanceDialog.cpp (renamed from launcher/dialogs/ExportInstanceDialog.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/dialogs/ExportInstanceDialog.h (renamed from launcher/dialogs/ExportInstanceDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ExportInstanceDialog.ui (renamed from launcher/dialogs/ExportInstanceDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/IconPickerDialog.cpp (renamed from launcher/dialogs/IconPickerDialog.cpp) | 14 | ||||
-rw-r--r-- | launcher/ui/dialogs/IconPickerDialog.h (renamed from launcher/dialogs/IconPickerDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/IconPickerDialog.ui (renamed from launcher/dialogs/IconPickerDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/LoginDialog.cpp (renamed from launcher/dialogs/LoginDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/LoginDialog.h (renamed from launcher/dialogs/LoginDialog.h) | 3 | ||||
-rw-r--r-- | launcher/ui/dialogs/LoginDialog.ui (renamed from launcher/dialogs/LoginDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/MSALoginDialog.cpp (renamed from launcher/dialogs/MSALoginDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/MSALoginDialog.h (renamed from launcher/dialogs/MSALoginDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/MSALoginDialog.ui (renamed from launcher/dialogs/MSALoginDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewComponentDialog.cpp (renamed from launcher/dialogs/NewComponentDialog.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewComponentDialog.h (renamed from launcher/dialogs/NewComponentDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewComponentDialog.ui (renamed from launcher/dialogs/NewComponentDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewInstanceDialog.cpp (renamed from launcher/dialogs/NewInstanceDialog.cpp) | 40 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewInstanceDialog.h (renamed from launcher/dialogs/NewInstanceDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewInstanceDialog.ui (renamed from launcher/dialogs/NewInstanceDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NotificationDialog.cpp (renamed from launcher/dialogs/NotificationDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NotificationDialog.h (renamed from launcher/dialogs/NotificationDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/NotificationDialog.ui (renamed from launcher/dialogs/NotificationDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSelectDialog.cpp (renamed from launcher/dialogs/ProfileSelectDialog.cpp) | 9 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSelectDialog.h (renamed from launcher/dialogs/ProfileSelectDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSelectDialog.ui (renamed from launcher/dialogs/ProfileSelectDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSetupDialog.cpp | 250 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSetupDialog.h | 88 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProfileSetupDialog.ui | 74 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProgressDialog.cpp (renamed from launcher/dialogs/ProgressDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProgressDialog.h (renamed from launcher/dialogs/ProgressDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/ProgressDialog.ui (renamed from launcher/dialogs/ProgressDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/SkinUploadDialog.cpp (renamed from launcher/dialogs/SkinUploadDialog.cpp) | 9 | ||||
-rw-r--r-- | launcher/ui/dialogs/SkinUploadDialog.h (renamed from launcher/dialogs/SkinUploadDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/SkinUploadDialog.ui (renamed from launcher/dialogs/SkinUploadDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/UpdateDialog.cpp (renamed from launcher/dialogs/UpdateDialog.cpp) | 14 | ||||
-rw-r--r-- | launcher/ui/dialogs/UpdateDialog.h (renamed from launcher/dialogs/UpdateDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/dialogs/UpdateDialog.ui (renamed from launcher/dialogs/UpdateDialog.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/dialogs/VersionSelectDialog.cpp (renamed from launcher/dialogs/VersionSelectDialog.cpp) | 18 | ||||
-rw-r--r-- | launcher/ui/dialogs/VersionSelectDialog.h (renamed from launcher/dialogs/VersionSelectDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/AccessibleInstanceView.cpp (renamed from launcher/instanceview/AccessibleInstanceView.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/AccessibleInstanceView.h (renamed from launcher/instanceview/AccessibleInstanceView.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/AccessibleInstanceView_p.h (renamed from launcher/instanceview/AccessibleInstanceView_p.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceDelegate.cpp (renamed from launcher/instanceview/InstanceDelegate.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceDelegate.h (renamed from launcher/instanceview/InstanceDelegate.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceProxyModel.cpp (renamed from launcher/instanceview/InstanceProxyModel.cpp) | 6 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceProxyModel.h (renamed from launcher/instanceview/InstanceProxyModel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceView.cpp (renamed from launcher/instanceview/InstanceView.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/instanceview/InstanceView.h (renamed from launcher/instanceview/InstanceView.h) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/VisualGroup.cpp (renamed from launcher/instanceview/VisualGroup.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/instanceview/VisualGroup.h (renamed from launcher/instanceview/VisualGroup.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pagedialog/PageDialog.cpp (renamed from launcher/pagedialog/PageDialog.cpp) | 11 | ||||
-rw-r--r-- | launcher/ui/pagedialog/PageDialog.h (renamed from launcher/pagedialog/PageDialog.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/BasePage.h (renamed from launcher/pages/BasePage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/BasePageContainer.h (renamed from launcher/pages/BasePageContainer.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/BasePageProvider.h (renamed from launcher/pages/BasePageProvider.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/global/AccountListPage.cpp (renamed from launcher/pages/global/AccountListPage.cpp) | 53 | ||||
-rw-r--r-- | launcher/ui/pages/global/AccountListPage.h (renamed from launcher/pages/global/AccountListPage.h) | 10 | ||||
-rw-r--r-- | launcher/ui/pages/global/AccountListPage.ui (renamed from launcher/pages/global/AccountListPage.ui) | 4 | ||||
-rw-r--r-- | launcher/ui/pages/global/CustomCommandsPage.cpp (renamed from launcher/pages/global/CustomCommandsPage.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/pages/global/CustomCommandsPage.h (renamed from launcher/pages/global/CustomCommandsPage.h) | 8 | ||||
-rw-r--r-- | launcher/ui/pages/global/ExternalToolsPage.cpp (renamed from launcher/pages/global/ExternalToolsPage.cpp) | 18 | ||||
-rw-r--r-- | launcher/ui/pages/global/ExternalToolsPage.h (renamed from launcher/pages/global/ExternalToolsPage.h) | 8 | ||||
-rw-r--r-- | launcher/ui/pages/global/ExternalToolsPage.ui (renamed from launcher/pages/global/ExternalToolsPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/global/JavaPage.cpp (renamed from launcher/pages/global/JavaPage.cpp) | 10 | ||||
-rw-r--r-- | launcher/ui/pages/global/JavaPage.h (renamed from launcher/pages/global/JavaPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/JavaPage.ui (renamed from launcher/pages/global/JavaPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/global/LanguagePage.cpp (renamed from launcher/pages/global/LanguagePage.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/pages/global/LanguagePage.h (renamed from launcher/pages/global/LanguagePage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/LauncherPage.cpp (renamed from launcher/pages/global/LauncherPage.cpp) | 30 | ||||
-rw-r--r-- | launcher/ui/pages/global/LauncherPage.h (renamed from launcher/pages/global/LauncherPage.h) | 8 | ||||
-rw-r--r-- | launcher/ui/pages/global/LauncherPage.ui (renamed from launcher/pages/global/LauncherPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/global/MinecraftPage.cpp (renamed from launcher/pages/global/MinecraftPage.cpp) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/MinecraftPage.h (renamed from launcher/pages/global/MinecraftPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/MinecraftPage.ui (renamed from launcher/pages/global/MinecraftPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/global/PasteEEPage.cpp (renamed from launcher/pages/global/PasteEEPage.cpp) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/PasteEEPage.h (renamed from launcher/pages/global/PasteEEPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/PasteEEPage.ui (renamed from launcher/pages/global/PasteEEPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/global/ProxyPage.cpp (renamed from launcher/pages/global/ProxyPage.cpp) | 17 | ||||
-rw-r--r-- | launcher/ui/pages/global/ProxyPage.h (renamed from launcher/pages/global/ProxyPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/ProxyPage.ui (renamed from launcher/pages/global/ProxyPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/GameOptionsPage.cpp (renamed from launcher/pages/instance/GameOptionsPage.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/GameOptionsPage.h (renamed from launcher/pages/instance/GameOptionsPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/GameOptionsPage.ui (renamed from launcher/pages/instance/GameOptionsPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/InstanceSettingsPage.cpp (renamed from launcher/pages/instance/InstanceSettingsPage.cpp) | 27 | ||||
-rw-r--r-- | launcher/ui/pages/instance/InstanceSettingsPage.h (renamed from launcher/pages/instance/InstanceSettingsPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/InstanceSettingsPage.ui (renamed from launcher/pages/instance/InstanceSettingsPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LegacyUpgradePage.cpp (renamed from launcher/pages/instance/LegacyUpgradePage.cpp) | 11 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LegacyUpgradePage.h (renamed from launcher/pages/instance/LegacyUpgradePage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LegacyUpgradePage.ui (renamed from launcher/pages/instance/LegacyUpgradePage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LogPage.cpp (renamed from launcher/pages/instance/LogPage.cpp) | 14 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LogPage.h (renamed from launcher/pages/instance/LogPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/LogPage.ui (renamed from launcher/pages/instance/LogPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ModFolderPage.cpp (renamed from launcher/pages/instance/ModFolderPage.cpp) | 15 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ModFolderPage.h (renamed from launcher/pages/instance/ModFolderPage.h) | 7 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ModFolderPage.ui (renamed from launcher/pages/instance/ModFolderPage.ui) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/NotesPage.cpp (renamed from launcher/pages/instance/NotesPage.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/NotesPage.h (renamed from launcher/pages/instance/NotesPage.h) | 8 | ||||
-rw-r--r-- | launcher/ui/pages/instance/NotesPage.ui (renamed from launcher/pages/instance/NotesPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/OtherLogsPage.cpp (renamed from launcher/pages/instance/OtherLogsPage.cpp) | 7 | ||||
-rw-r--r-- | launcher/ui/pages/instance/OtherLogsPage.h (renamed from launcher/pages/instance/OtherLogsPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/OtherLogsPage.ui (renamed from launcher/pages/instance/OtherLogsPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ResourcePackPage.h (renamed from launcher/pages/instance/ResourcePackPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ScreenshotsPage.cpp (renamed from launcher/pages/instance/ScreenshotsPage.cpp) | 19 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ScreenshotsPage.h (renamed from launcher/pages/instance/ScreenshotsPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ScreenshotsPage.ui (renamed from launcher/pages/instance/ScreenshotsPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ServersPage.cpp (renamed from launcher/pages/instance/ServersPage.cpp) | 4 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ServersPage.h (renamed from launcher/pages/instance/ServersPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ServersPage.ui (renamed from launcher/pages/instance/ServersPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ShaderPackPage.h (renamed from launcher/pages/instance/ShaderPackPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/TexturePackPage.h (renamed from launcher/pages/instance/TexturePackPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/instance/VersionPage.cpp (renamed from launcher/pages/instance/VersionPage.cpp) | 49 | ||||
-rw-r--r-- | launcher/ui/pages/instance/VersionPage.h (renamed from launcher/pages/instance/VersionPage.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/instance/VersionPage.ui (renamed from launcher/pages/instance/VersionPage.ui) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/WorldListPage.cpp (renamed from launcher/pages/instance/WorldListPage.cpp) | 22 | ||||
-rw-r--r-- | launcher/ui/pages/instance/WorldListPage.h (renamed from launcher/pages/instance/WorldListPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/instance/WorldListPage.ui (renamed from launcher/pages/instance/WorldListPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ImportPage.cpp (renamed from launcher/pages/modplatform/ImportPage.cpp) | 8 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ImportPage.h (renamed from launcher/pages/modplatform/ImportPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ImportPage.ui (renamed from launcher/pages/modplatform/ImportPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/VanillaPage.cpp (renamed from launcher/pages/modplatform/VanillaPage.cpp) | 17 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/VanillaPage.h (renamed from launcher/pages/modplatform/VanillaPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/VanillaPage.ui (renamed from launcher/pages/modplatform/VanillaPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp (renamed from launcher/pages/modplatform/atlauncher/AtlFilterModel.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h (renamed from launcher/pages/modplatform/atlauncher/AtlFilterModel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp (renamed from launcher/pages/modplatform/atlauncher/AtlListModel.cpp) | 13 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlListModel.h (renamed from launcher/pages/modplatform/atlauncher/AtlListModel.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp (renamed from launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h (renamed from launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui (renamed from launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp (renamed from launcher/pages/modplatform/atlauncher/AtlPage.cpp) | 10 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlPage.h (renamed from launcher/pages/modplatform/atlauncher/AtlPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/atlauncher/AtlPage.ui (renamed from launcher/pages/modplatform/atlauncher/AtlPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/flame/FlameModel.cpp (renamed from launcher/pages/modplatform/flame/FlameModel.cpp) | 13 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/flame/FlameModel.h (renamed from launcher/pages/modplatform/flame/FlameModel.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/flame/FlamePage.cpp (renamed from launcher/pages/modplatform/flame/FlamePage.cpp) | 15 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/flame/FlamePage.h (renamed from launcher/pages/modplatform/flame/FlamePage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/flame/FlamePage.ui (renamed from launcher/pages/modplatform/flame/FlamePage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp (renamed from launcher/pages/modplatform/ftb/FtbFilterModel.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbFilterModel.h (renamed from launcher/pages/modplatform/ftb/FtbFilterModel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbListModel.cpp (renamed from launcher/pages/modplatform/ftb/FtbListModel.cpp) | 15 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbListModel.h (renamed from launcher/pages/modplatform/ftb/FtbListModel.h) | 4 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbPage.cpp (renamed from launcher/pages/modplatform/ftb/FtbPage.cpp) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbPage.h (renamed from launcher/pages/modplatform/ftb/FtbPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ftb/FtbPage.ui (renamed from launcher/pages/modplatform/ftb/FtbPage.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp (renamed from launcher/pages/modplatform/legacy_ftb/ListModel.cpp) | 11 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/legacy_ftb/ListModel.h (renamed from launcher/pages/modplatform/legacy_ftb/ListModel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/legacy_ftb/Page.cpp (renamed from launcher/pages/modplatform/legacy_ftb/Page.cpp) | 12 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/legacy_ftb/Page.h (renamed from launcher/pages/modplatform/legacy_ftb/Page.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/legacy_ftb/Page.ui (renamed from launcher/pages/modplatform/legacy_ftb/Page.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicData.h (renamed from launcher/pages/modplatform/technic/TechnicData.h) | 0 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicModel.cpp (renamed from launcher/pages/modplatform/technic/TechnicModel.cpp) | 13 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicModel.h (renamed from launcher/pages/modplatform/technic/TechnicModel.h) | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicPage.cpp (renamed from launcher/pages/modplatform/technic/TechnicPage.cpp) | 13 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicPage.h (renamed from launcher/pages/modplatform/technic/TechnicPage.h) | 6 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/technic/TechnicPage.ui (renamed from launcher/pages/modplatform/technic/TechnicPage.ui) | 2 | ||||
-rw-r--r-- | launcher/ui/setupwizard/AnalyticsWizardPage.cpp (renamed from launcher/setupwizard/AnalyticsWizardPage.cpp) | 6 | ||||
-rw-r--r-- | launcher/ui/setupwizard/AnalyticsWizardPage.h (renamed from launcher/setupwizard/AnalyticsWizardPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/setupwizard/BaseWizardPage.h (renamed from launcher/setupwizard/BaseWizardPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/setupwizard/JavaWizardPage.cpp (renamed from launcher/setupwizard/JavaWizardPage.cpp) | 24 | ||||
-rw-r--r-- | launcher/ui/setupwizard/JavaWizardPage.h (renamed from launcher/setupwizard/JavaWizardPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/setupwizard/LanguageWizardPage.cpp (renamed from launcher/setupwizard/LanguageWizardPage.cpp) | 8 | ||||
-rw-r--r-- | launcher/ui/setupwizard/LanguageWizardPage.h (renamed from launcher/setupwizard/LanguageWizardPage.h) | 0 | ||||
-rw-r--r-- | launcher/ui/setupwizard/SetupWizard.cpp (renamed from launcher/setupwizard/SetupWizard.cpp) | 2 | ||||
-rw-r--r-- | launcher/ui/setupwizard/SetupWizard.h (renamed from launcher/setupwizard/SetupWizard.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/BrightTheme.cpp (renamed from launcher/themes/BrightTheme.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/BrightTheme.h (renamed from launcher/themes/BrightTheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/CustomTheme.cpp (renamed from launcher/themes/CustomTheme.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/CustomTheme.h (renamed from launcher/themes/CustomTheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/DarkTheme.cpp (renamed from launcher/themes/DarkTheme.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/DarkTheme.h (renamed from launcher/themes/DarkTheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/FusionTheme.cpp (renamed from launcher/themes/FusionTheme.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/FusionTheme.h (renamed from launcher/themes/FusionTheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/ITheme.cpp (renamed from launcher/themes/ITheme.cpp) | 6 | ||||
-rw-r--r-- | launcher/ui/themes/ITheme.h (renamed from launcher/themes/ITheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/SystemTheme.cpp (renamed from launcher/themes/SystemTheme.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/themes/SystemTheme.h (renamed from launcher/themes/SystemTheme.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/Common.cpp (renamed from launcher/widgets/Common.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/Common.h (renamed from launcher/widgets/Common.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/CustomCommands.cpp (renamed from launcher/widgets/CustomCommands.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/CustomCommands.h (renamed from launcher/widgets/CustomCommands.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/CustomCommands.ui (renamed from launcher/widgets/CustomCommands.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/DropLabel.cpp (renamed from launcher/widgets/DropLabel.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/DropLabel.h (renamed from launcher/widgets/DropLabel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/FocusLineEdit.cpp (renamed from launcher/widgets/FocusLineEdit.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/FocusLineEdit.h (renamed from launcher/widgets/FocusLineEdit.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/IconLabel.cpp (renamed from launcher/widgets/IconLabel.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/IconLabel.h (renamed from launcher/widgets/IconLabel.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/InstanceCardWidget.ui (renamed from launcher/widgets/InstanceCardWidget.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/JavaSettingsWidget.cpp (renamed from launcher/widgets/JavaSettingsWidget.cpp) | 31 | ||||
-rw-r--r-- | launcher/ui/widgets/JavaSettingsWidget.h (renamed from launcher/widgets/JavaSettingsWidget.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LabeledToolButton.cpp (renamed from launcher/widgets/LabeledToolButton.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LabeledToolButton.h (renamed from launcher/widgets/LabeledToolButton.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LanguageSelectionWidget.cpp (renamed from launcher/widgets/LanguageSelectionWidget.cpp) | 8 | ||||
-rw-r--r-- | launcher/ui/widgets/LanguageSelectionWidget.h (renamed from launcher/widgets/LanguageSelectionWidget.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LineSeparator.cpp (renamed from launcher/widgets/LineSeparator.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LineSeparator.h (renamed from launcher/widgets/LineSeparator.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LogView.cpp (renamed from launcher/widgets/LogView.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/LogView.h (renamed from launcher/widgets/LogView.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/MCModInfoFrame.cpp (renamed from launcher/widgets/MCModInfoFrame.cpp) | 3 | ||||
-rw-r--r-- | launcher/ui/widgets/MCModInfoFrame.h (renamed from launcher/widgets/MCModInfoFrame.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/MCModInfoFrame.ui (renamed from launcher/widgets/MCModInfoFrame.ui) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/ModListView.cpp (renamed from launcher/widgets/ModListView.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/ModListView.h (renamed from launcher/widgets/ModListView.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/PageContainer.cpp (renamed from launcher/widgets/PageContainer.cpp) | 17 | ||||
-rw-r--r-- | launcher/ui/widgets/PageContainer.h (renamed from launcher/widgets/PageContainer.h) | 4 | ||||
-rw-r--r-- | launcher/ui/widgets/PageContainer_p.h (renamed from launcher/widgets/PageContainer_p.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/ProgressWidget.cpp (renamed from launcher/widgets/ProgressWidget.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/ProgressWidget.h (renamed from launcher/widgets/ProgressWidget.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/VersionListView.cpp (renamed from launcher/widgets/VersionListView.cpp) | 1 | ||||
-rw-r--r-- | launcher/ui/widgets/VersionListView.h (renamed from launcher/widgets/VersionListView.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/VersionSelectWidget.cpp (renamed from launcher/widgets/VersionSelectWidget.cpp) | 9 | ||||
-rw-r--r-- | launcher/ui/widgets/VersionSelectWidget.h (renamed from launcher/widgets/VersionSelectWidget.h) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/WideBar.cpp (renamed from launcher/widgets/WideBar.cpp) | 0 | ||||
-rw-r--r-- | launcher/ui/widgets/WideBar.h (renamed from launcher/widgets/WideBar.h) | 0 | ||||
-rw-r--r-- | launcher/updater/DownloadTask.cpp | 14 | ||||
-rw-r--r-- | launcher/updater/DownloadTask.h | 9 | ||||
-rw-r--r-- | launcher/updater/GoUpdate.cpp | 2 | ||||
-rw-r--r-- | launcher/updater/GoUpdate.h | 2 | ||||
-rw-r--r-- | launcher/updater/UpdateChecker.cpp | 38 | ||||
-rw-r--r-- | launcher/updater/UpdateChecker.h | 8 | ||||
-rw-r--r-- | launcher/updater/UpdateChecker_test.cpp | 6 | ||||
-rw-r--r-- | libraries/LocalPeer/CMakeLists.txt | 3 | ||||
-rw-r--r-- | libraries/katabasis/CMakeLists.txt | 6 | ||||
-rw-r--r-- | libraries/katabasis/include/katabasis/Bits.h | 6 | ||||
-rw-r--r-- | libraries/katabasis/include/katabasis/DeviceFlow.h | 150 | ||||
-rw-r--r-- | libraries/katabasis/include/katabasis/OAuth2.h | 233 | ||||
-rw-r--r-- | libraries/katabasis/include/katabasis/Reply.h | 7 | ||||
-rw-r--r-- | libraries/katabasis/include/katabasis/ReplyServer.h | 53 | ||||
-rw-r--r-- | libraries/katabasis/src/DeviceFlow.cpp | 451 | ||||
-rw-r--r-- | libraries/katabasis/src/OAuth2.cpp | 672 | ||||
-rw-r--r-- | libraries/katabasis/src/Reply.cpp | 17 | ||||
-rwxr-xr-x | libraries/katabasis/src/ReplyServer.cpp | 182 |
382 files changed, 3654 insertions, 3707 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf93758..e45dbf7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,7 @@ if(Launcher_LAYOUT_REAL STREQUAL "mac-bundle") set(INSTALL_BUNDLE "full") # Add the icon - install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR}) + install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR} RENAME ${Launcher_Name}.icns) elseif(Launcher_LAYOUT_REAL STREQUAL "lin-nodeps") set(BINARY_DEST_DIR "bin") diff --git a/doc/multimc.1.txt b/doc/multimc.1.txt index eaf77f8f..da65af2e 100644 --- a/doc/multimc.1.txt +++ b/doc/multimc.1.txt @@ -36,6 +36,8 @@ OPTIONS *-v, --version*:: Display program version and exit. +*-a, --profile*='PROFILE':: + Use the account specified by 'PROFILE' (only valid in combination with --launch). EXIT STATUS ----------- diff --git a/launcher/Launcher.cpp b/launcher/Application.cpp index a69fb8f3..37724038 100644 --- a/launcher/Launcher.cpp +++ b/launcher/Application.cpp @@ -1,36 +1,42 @@ -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" -#include "MainWindow.h" -#include "InstanceWindow.h" -#include "instanceview/AccessibleInstanceView.h" -#include <QAccessible> +#include "ui/MainWindow.h" +#include "ui/InstanceWindow.h" + +#include "ui/instanceview/AccessibleInstanceView.h" + +#include "ui/pages/BasePageProvider.h" +#include "ui/pages/global/LauncherPage.h" +#include "ui/pages/global/MinecraftPage.h" +#include "ui/pages/global/JavaPage.h" +#include "ui/pages/global/LanguagePage.h" +#include "ui/pages/global/ProxyPage.h" +#include "ui/pages/global/ExternalToolsPage.h" +#include "ui/pages/global/AccountListPage.h" +#include "ui/pages/global/PasteEEPage.h" +#include "ui/pages/global/CustomCommandsPage.h" + +#include "ui/themes/ITheme.h" +#include "ui/themes/SystemTheme.h" +#include "ui/themes/DarkTheme.h" +#include "ui/themes/BrightTheme.h" +#include "ui/themes/CustomTheme.h" -#include "pages/BasePageProvider.h" -#include "pages/global/LauncherPage.h" -#include "pages/global/MinecraftPage.h" -#include "pages/global/JavaPage.h" -#include "pages/global/LanguagePage.h" -#include "pages/global/ProxyPage.h" -#include "pages/global/ExternalToolsPage.h" -#include "pages/global/AccountListPage.h" -#include "pages/global/PasteEEPage.h" -#include "pages/global/CustomCommandsPage.h" - -#include "themes/ITheme.h" -#include "themes/SystemTheme.h" -#include "themes/DarkTheme.h" -#include "themes/BrightTheme.h" -#include "themes/CustomTheme.h" - -#include "LauncherMessage.h" - -#include "setupwizard/SetupWizard.h" -#include "setupwizard/LanguageWizardPage.h" -#include "setupwizard/JavaWizardPage.h" -#include "setupwizard/AnalyticsWizardPage.h" +#include "ui/setupwizard/SetupWizard.h" +#include "ui/setupwizard/LanguageWizardPage.h" +#include "ui/setupwizard/JavaWizardPage.h" +#include "ui/setupwizard/AnalyticsWizardPage.h" + +#include "ui/dialogs/CustomMessageBox.h" + +#include "ui/pagedialog/PageDialog.h" + +#include "ApplicationMessage.h" #include <iostream> + +#include <QAccessible> #include <QDir> #include <QFileInfo> #include <QNetworkAccessManager> @@ -41,13 +47,11 @@ #include <QDebug> #include <QStyleFactory> -#include "dialogs/CustomMessageBox.h" #include "InstanceList.h" #include <minecraft/auth/AccountList.h> #include "icons/IconList.h" #include "net/HttpMetaCache.h" -#include "Env.h" #include "java/JavaUtils.h" @@ -62,6 +66,7 @@ #include "settings/Setting.h" #include "translations/TranslationsModel.h" +#include "meta/Index.h" #include <Commandline.h> #include <FileSystem.h> @@ -71,7 +76,7 @@ #include <ganalytics.h> #include <sys.h> -#include "pagedialog/PageDialog.h" +#include <Secrets.h> #if defined Q_OS_WIN32 @@ -99,7 +104,7 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QSt const char *levels = "DWCFIS"; const QString format("%1 %2 %3\n"); - qint64 msecstotal = LAUNCHER->timeSinceStart(); + qint64 msecstotal = APPLICATION->timeSinceStart(); qint64 seconds = msecstotal / 1000; qint64 msecs = msecstotal % 1000; QString foo; @@ -108,8 +113,8 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QSt QString out = format.arg(buf).arg(levels[type]).arg(msg); - LAUNCHER->logFile->write(out.toUtf8()); - LAUNCHER->logFile->flush(); + APPLICATION->logFile->write(out.toUtf8()); + APPLICATION->logFile->flush(); QTextStream(stderr) << out.toLocal8Bit(); fflush(stderr); } @@ -155,7 +160,7 @@ QString getIdealPlatform(QString currentPlatform) { } -Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) +Application::Application(int &argc, char **argv) : QApplication(argc, argv) { #if defined Q_OS_WIN32 // attach the parent console @@ -261,7 +266,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) if(argc > 0) std::cerr << "Try '" << argv[0] << " -h' to get help on command line parameters." << std::endl; - m_status = Launcher::Failed; + m_status = Application::Failed; return; } @@ -269,7 +274,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) if (args["help"].toBool()) { std::cout << qPrintable(parser.compileHelp(arguments()[0])); - m_status = Launcher::Succeeded; + m_status = Application::Succeeded; return; } @@ -278,7 +283,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) { std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; - m_status = Launcher::Succeeded; + m_status = Application::Succeeded; return; } } @@ -347,14 +352,14 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) { std::cerr << "--server can only be used in combination with --launch!" << std::endl; - m_status = Launcher::Failed; + m_status = Application::Failed; return; } if(m_instanceIdToLaunch.isEmpty() && !m_profileToUse.isEmpty()) { std::cerr << "--account can only be used in combination with --launch!" << std::endl; - m_status = Launcher::Failed; + m_status = Application::Failed; return; } @@ -430,19 +435,19 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) { // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates. m_peerInstance = new LocalPeer(this, appID); - connect(m_peerInstance, &LocalPeer::messageReceived, this, &Launcher::messageReceived); + connect(m_peerInstance, &LocalPeer::messageReceived, this, &Application::messageReceived); if(m_peerInstance->isClient()) { int timeout = 2000; if(m_instanceIdToLaunch.isEmpty()) { - LauncherMessage activate; + ApplicationMessage activate; activate.command = "activate"; m_peerInstance->sendMessage(activate.serialize(), timeout); if(!m_zipToImport.isEmpty()) { - LauncherMessage import; + ApplicationMessage import; import.command = "import"; import.args.insert("path", m_zipToImport.toString()); m_peerInstance->sendMessage(import.serialize(), timeout); @@ -450,7 +455,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) } else { - LauncherMessage launch; + ApplicationMessage launch; launch.command = "launch"; launch.args["id"] = m_instanceIdToLaunch; @@ -464,7 +469,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) } m_peerInstance->sendMessage(launch.serialize(), timeout); } - m_status = Launcher::Succeeded; + m_status = Application::Succeeded; return; } } @@ -519,10 +524,6 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) FS::updateTimestamp(m_rootPath); #endif -#ifdef MULTIMC_JARS_LOCATION - ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); -#endif - qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; @@ -729,6 +730,18 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) QAccessible::installFactory(groupViewAccessibleFactory); #endif /* !QT_NO_ACCESSIBILITY */ + // initialize network access and proxy setup + { + m_network = new QNetworkAccessManager(); + QString proxyTypeStr = settings()->get("ProxyType").toString(); + QString addr = settings()->get("ProxyAddr").toString(); + int port = settings()->get("ProxyPort").value<qint16>(); + QString user = settings()->get("ProxyUser").toString(); + QString pass = settings()->get("ProxyPass").toString(); + updateProxySettings(proxyTypeStr, addr, port, user, pass); + qDebug() << "<> Network done."; + } + // load translations { m_translations.reset(new TranslationsModel("translations")); @@ -744,13 +757,13 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) auto platform = getIdealPlatform(BuildConfig.BUILD_PLATFORM); auto channelUrl = BuildConfig.UPDATER_BASE + platform + "/channels.json"; qDebug() << "Initializing updater with platform: " << platform << " -- " << channelUrl; - m_updateChecker.reset(new UpdateChecker(channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); + m_updateChecker.reset(new UpdateChecker(m_network, channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); qDebug() << "<> Updater started."; } // Instance icons { - auto setting = LAUNCHER->settings()->getSetting("IconsDir"); + auto setting = APPLICATION->settings()->getSetting("IconsDir"); QStringList instFolders = { ":/icons/multimc/32x32/instances/", @@ -763,7 +776,6 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) { m_icons->directoryChanged(value.toString()); }); - ENV.registerIconList(m_icons); qDebug() << "<> Instance icons intialized."; } @@ -820,21 +832,28 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) // init the http meta cache { - ENV.initHttpMetaCache(); + m_metacache.reset(new HttpMetaCache("metacache")); + m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath()); + m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath()); + m_metacache->addBase("versions", QDir("versions").absolutePath()); + m_metacache->addBase("libraries", QDir("libraries").absolutePath()); + m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath()); + m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath()); + m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); + m_metacache->addBase("general", QDir("cache").absolutePath()); + m_metacache->addBase("ATLauncherPacks", QDir("cache/ATLauncherPacks").absolutePath()); + m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath()); + m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath()); + m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath()); + m_metacache->addBase("FlamePacks", QDir("cache/FlamePacks").absolutePath()); + m_metacache->addBase("root", QDir::currentPath()); + m_metacache->addBase("translations", QDir("translations").absolutePath()); + m_metacache->addBase("icons", QDir("cache/icons").absolutePath()); + m_metacache->addBase("meta", QDir("meta").absolutePath()); + m_metacache->Load(); qDebug() << "<> Cache initialized."; } - // init proxy settings - { - QString proxyTypeStr = settings()->get("ProxyType").toString(); - QString addr = settings()->get("ProxyAddr").toString(); - int port = settings()->get("ProxyPort").value<qint16>(); - QString user = settings()->get("ProxyUser").toString(); - QString pass = settings()->get("ProxyPass").toString(); - ENV.updateProxySettings(proxyTypeStr, addr, port, user, pass); - qDebug() << "<> Proxy settings done."; - } - // now we have network, download translation updates m_translations->downloadIndex(); @@ -851,7 +870,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) m_mcedit.reset(new MCEditTool(m_settings)); } - connect(this, &Launcher::aboutToQuit, [this](){ + connect(this, &Application::aboutToQuit, [this](){ if(m_instances) { // save any remaining instance state @@ -881,7 +900,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) } auto analyticsSetting = m_settings->getSetting("Analytics"); - connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Launcher::analyticsSettingChanged); + connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Application::analyticsSettingChanged); QString clientID = m_settings->get("AnalyticsClientID").toString(); if(clientID.isEmpty()) { @@ -893,7 +912,8 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this); m_analytics->setLogLevel(GAnalytics::Debug); m_analytics->setAnonymizeIPs(true); - m_analytics->setNetworkAccessManager(&ENV.qnam()); + // FIXME: the ganalytics library has no idea about our fancy shared pointers... + m_analytics->setNetworkAccessManager(network().get()); if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version()) { @@ -917,7 +937,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) performMainStartupAction(); } -bool Launcher::createSetupWizard() +bool Application::createSetupWizard() { bool javaRequired = [&]() { @@ -975,22 +995,22 @@ bool Launcher::createSetupWizard() { m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard)); } - connect(m_setupWizard, &QDialog::finished, this, &Launcher::setupWizardFinished); + connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished); m_setupWizard->show(); return true; } return false; } -void Launcher::setupWizardFinished(int status) +void Application::setupWizardFinished(int status) { qDebug() << "Wizard result =" << status; performMainStartupAction(); } -void Launcher::performMainStartupAction() +void Application::performMainStartupAction() { - m_status = Launcher::Initialized; + m_status = Application::Initialized; if(!m_instanceIdToLaunch.isEmpty()) { auto inst = instances()->getInstanceById(m_instanceIdToLaunch); @@ -1033,18 +1053,15 @@ void Launcher::performMainStartupAction() } } -void Launcher::showFatalErrorMessage(const QString& title, const QString& content) +void Application::showFatalErrorMessage(const QString& title, const QString& content) { - m_status = Launcher::Failed; + m_status = Application::Failed; auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); dialog->exec(); } -Launcher::~Launcher() +Application::~Application() { - // kill the other globals. - Env::dispose(); - // Shut down logger by setting the logger function to nothing qInstallMessageHandler(nullptr); @@ -1060,7 +1077,7 @@ Launcher::~Launcher() #endif } -void Launcher::messageReceived(const QByteArray& message) +void Application::messageReceived(const QByteArray& message) { if(status() != Initialized) { @@ -1068,7 +1085,7 @@ void Launcher::messageReceived(const QByteArray& message) return; } - LauncherMessage received; + ApplicationMessage received; received.parse(message); auto & command = received.command; @@ -1134,7 +1151,7 @@ void Launcher::messageReceived(const QByteArray& message) } } -void Launcher::analyticsSettingChanged(const Setting&, QVariant value) +void Application::analyticsSettingChanged(const Setting&, QVariant value) { if(!m_analytics) return; @@ -1150,12 +1167,12 @@ void Launcher::analyticsSettingChanged(const Setting&, QVariant value) m_analytics->enable(enabled); } -std::shared_ptr<TranslationsModel> Launcher::translations() +std::shared_ptr<TranslationsModel> Application::translations() { return m_translations; } -std::shared_ptr<JavaInstallList> Launcher::javalist() +std::shared_ptr<JavaInstallList> Application::javalist() { if (!m_javalist) { @@ -1164,7 +1181,7 @@ std::shared_ptr<JavaInstallList> Launcher::javalist() return m_javalist; } -std::vector<ITheme *> Launcher::getValidApplicationThemes() +std::vector<ITheme *> Application::getValidApplicationThemes() { std::vector<ITheme *> ret; auto iter = m_themes.cbegin(); @@ -1176,7 +1193,7 @@ std::vector<ITheme *> Launcher::getValidApplicationThemes() return ret; } -void Launcher::setApplicationTheme(const QString& name, bool initial) +void Application::setApplicationTheme(const QString& name, bool initial) { auto systemPalette = qApp->palette(); auto themeIter = m_themes.find(name); @@ -1191,12 +1208,12 @@ void Launcher::setApplicationTheme(const QString& name, bool initial) } } -void Launcher::setIconTheme(const QString& name) +void Application::setIconTheme(const QString& name) { XdgIcon::setThemeName(name); } -QIcon Launcher::getThemedIcon(const QString& name) +QIcon Application::getThemedIcon(const QString& name) { if(name == "logo") { return QIcon(":/logo.svg"); @@ -1204,7 +1221,7 @@ QIcon Launcher::getThemedIcon(const QString& name) return XdgIcon::fromTheme(name); } -bool Launcher::openJsonEditor(const QString &filename) +bool Application::openJsonEditor(const QString &filename) { const QString file = QDir::current().absoluteFilePath(filename); if (m_settings->get("JsonEditor").toString().isEmpty()) @@ -1218,7 +1235,7 @@ bool Launcher::openJsonEditor(const QString &filename) } } -bool Launcher::launch( +bool Application::launch( InstancePtr instance, bool online, BaseProfilerFactory *profiler, @@ -1255,8 +1272,8 @@ bool Launcher::launch( { controller->setParentWidget(m_mainWindow); } - connect(controller.get(), &LaunchController::succeeded, this, &Launcher::controllerSucceeded); - connect(controller.get(), &LaunchController::failed, this, &Launcher::controllerFailed); + connect(controller.get(), &LaunchController::succeeded, this, &Application::controllerSucceeded); + connect(controller.get(), &LaunchController::failed, this, &Application::controllerFailed); addRunningInstance(); controller->start(); return true; @@ -1274,7 +1291,7 @@ bool Launcher::launch( return false; } -bool Launcher::kill(InstancePtr instance) +bool Application::kill(InstancePtr instance) { if (!instance->isRunning()) { @@ -1291,7 +1308,7 @@ bool Launcher::kill(InstancePtr instance) return true; } -void Launcher::addRunningInstance() +void Application::addRunningInstance() { m_runningInstances ++; if(m_runningInstances == 1) @@ -1300,7 +1317,7 @@ void Launcher::addRunningInstance() } } -void Launcher::subRunningInstance() +void Application::subRunningInstance() { if(m_runningInstances == 0) { @@ -1314,23 +1331,23 @@ void Launcher::subRunningInstance() } } -bool Launcher::shouldExitNow() const +bool Application::shouldExitNow() const { return m_runningInstances == 0 && m_openWindows == 0; } -bool Launcher::updatesAreAllowed() +bool Application::updatesAreAllowed() { return m_runningInstances == 0; } -void Launcher::updateIsRunning(bool running) +void Application::updateIsRunning(bool running) { m_updateRunning = running; } -void Launcher::controllerSucceeded() +void Application::controllerSucceeded() { auto controller = qobject_cast<LaunchController *>(QObject::sender()); if(!controller) @@ -1357,7 +1374,7 @@ void Launcher::controllerSucceeded() } } -void Launcher::controllerFailed(const QString& error) +void Application::controllerFailed(const QString& error) { Q_UNUSED(error); auto controller = qobject_cast<LaunchController *>(QObject::sender()); @@ -1378,21 +1395,21 @@ void Launcher::controllerFailed(const QString& error) } } -void Launcher::ShowGlobalSettings(class QWidget* parent, QString open_page) +void Application::ShowGlobalSettings(class QWidget* parent, QString open_page) { if(!m_globalSettingsProvider) { return; } emit globalSettingsAboutToOpen(); { - SettingsObject::Lock lock(LAUNCHER->settings()); + SettingsObject::Lock lock(APPLICATION->settings()); PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); dlg.exec(); } emit globalSettingsClosed(); } -MainWindow* Launcher::showMainWindow(bool minimized) +MainWindow* Application::showMainWindow(bool minimized) { if(m_mainWindow) { @@ -1403,8 +1420,8 @@ MainWindow* Launcher::showMainWindow(bool minimized) else { m_mainWindow = new MainWindow(); - m_mainWindow->restoreState(QByteArray::fromBase64(LAUNCHER->settings()->get("MainWindowState").toByteArray())); - m_mainWindow->restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("MainWindowGeometry").toByteArray())); + m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); + m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); if(minimized) { m_mainWindow->showMinimized(); @@ -1415,8 +1432,8 @@ MainWindow* Launcher::showMainWindow(bool minimized) } m_mainWindow->checkInstancePathForProblems(); - connect(this, &Launcher::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); - connect(m_mainWindow, &MainWindow::isClosing, this, &Launcher::on_windowClose); + connect(this, &Application::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); + connect(m_mainWindow, &MainWindow::isClosing, this, &Application::on_windowClose); m_openWindows++; } // FIXME: move this somewhere else... @@ -1476,7 +1493,7 @@ MainWindow* Launcher::showMainWindow(bool minimized) return m_mainWindow; } -InstanceWindow *Launcher::showInstanceWindow(InstancePtr instance, QString page) +InstanceWindow *Application::showInstanceWindow(InstancePtr instance, QString page) { if(!instance) return nullptr; @@ -1493,7 +1510,7 @@ InstanceWindow *Launcher::showInstanceWindow(InstancePtr instance, QString page) { window = new InstanceWindow(instance); m_openWindows ++; - connect(window, &InstanceWindow::isClosing, this, &Launcher::on_windowClose); + connect(window, &InstanceWindow::isClosing, this, &Application::on_windowClose); } if(!page.isEmpty()) { @@ -1506,7 +1523,7 @@ InstanceWindow *Launcher::showInstanceWindow(InstancePtr instance, QString page) return window; } -void Launcher::on_windowClose() +void Application::on_windowClose() { m_openWindows--; auto instWindow = qobject_cast<InstanceWindow *>(QObject::sender()); @@ -1530,3 +1547,96 @@ void Launcher::on_windowClose() exit(0); } } + +QString Application::msaClientId() const { + return Secrets::getMSAClientID('-'); +} + +void Application::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password) +{ + // Set the application proxy settings. + if (proxyTypeStr == "SOCKS5") + { + QNetworkProxy::setApplicationProxy( + QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); + } + else if (proxyTypeStr == "HTTP") + { + QNetworkProxy::setApplicationProxy( + QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password)); + } + else if (proxyTypeStr == "None") + { + // If we have no proxy set, set no proxy and return. + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); + } + else + { + // If we have "Default" selected, set Qt to use the system proxy settings. + QNetworkProxyFactory::setUseSystemConfiguration(true); + } + + qDebug() << "Detecting proxy settings..."; + QNetworkProxy proxy = QNetworkProxy::applicationProxy(); + m_network->setProxy(proxy); + + QString proxyDesc; + if (proxy.type() == QNetworkProxy::NoProxy) + { + qDebug() << "Using no proxy is an option!"; + return; + } + switch (proxy.type()) + { + case QNetworkProxy::DefaultProxy: + proxyDesc = "Default proxy: "; + break; + case QNetworkProxy::Socks5Proxy: + proxyDesc = "Socks5 proxy: "; + break; + case QNetworkProxy::HttpProxy: + proxyDesc = "HTTP proxy: "; + break; + case QNetworkProxy::HttpCachingProxy: + proxyDesc = "HTTP caching: "; + break; + case QNetworkProxy::FtpCachingProxy: + proxyDesc = "FTP caching: "; + break; + default: + proxyDesc = "DERP proxy: "; + break; + } + proxyDesc += QString("%1:%2") + .arg(proxy.hostName()) + .arg(proxy.port()); + qDebug() << proxyDesc; +} + +shared_qobject_ptr< HttpMetaCache > Application::metacache() +{ + return m_metacache; +} + +shared_qobject_ptr<QNetworkAccessManager> Application::network() +{ + return m_network; +} + +shared_qobject_ptr<Meta::Index> Application::metadataIndex() +{ + if (!m_metadataIndex) + { + m_metadataIndex.reset(new Meta::Index()); + } + return m_metadataIndex; +} + +QString Application::getJarsPath() +{ + if(m_jarsPath.isEmpty()) + { + return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars"); + } + return m_jarsPath; +} diff --git a/launcher/Launcher.h b/launcher/Application.h index 8d97525f..1b2a2b60 100644 --- a/launcher/Launcher.h +++ b/launcher/Application.h @@ -18,7 +18,6 @@ class LocalPeer; class InstanceWindow; class MainWindow; class SetupWizard; -class FolderInstanceProvider; class GenericPageProvider; class QFile; class HttpMetaCache; @@ -36,18 +35,21 @@ class ITheme; class MCEditTool; class GAnalytics; -#if defined(LAUNCHER) -#undef LAUNCHER +namespace Meta { + class Index; +} + +#if defined(APPLICATION) +#undef APPLICATION #endif -#define LAUNCHER (static_cast<Launcher *>(QCoreApplication::instance())) +#define APPLICATION (static_cast<Application *>(QCoreApplication::instance())) -class Launcher : public QApplication +class Application : public QApplication { // friends for the purpose of limiting access to deprecated stuff Q_OBJECT public: - enum Status - { + enum Status { StartingUp, Failed, Succeeded, @@ -55,21 +57,18 @@ public: }; public: - Launcher(int &argc, char **argv); - virtual ~Launcher(); + Application(int &argc, char **argv); + virtual ~Application(); - GAnalytics *analytics() const - { + GAnalytics *analytics() const { return m_analytics; } - std::shared_ptr<SettingsObject> settings() const - { + std::shared_ptr<SettingsObject> settings() const { return m_settings; } - qint64 timeSinceStart() const - { + qint64 timeSinceStart() const { return startTime.msecsTo(QDateTime::currentDateTime()); } @@ -81,9 +80,7 @@ public: void setApplicationTheme(const QString& name, bool initial); - // DownloadUpdateTask - std::shared_ptr<UpdateChecker> updateChecker() - { + shared_qobject_ptr<UpdateChecker> updateChecker() { return m_updateChecker; } @@ -91,44 +88,44 @@ public: std::shared_ptr<JavaInstallList> javalist(); - std::shared_ptr<InstanceList> instances() const - { + std::shared_ptr<InstanceList> instances() const { return m_instances; } - FolderInstanceProvider * folderProvider() const - { - return m_instanceFolder; - } - - std::shared_ptr<IconList> icons() const - { + std::shared_ptr<IconList> icons() const { return m_icons; } - MCEditTool *mcedit() const - { + MCEditTool *mcedit() const { return m_mcedit.get(); } - std::shared_ptr<AccountList> accounts() const - { + shared_qobject_ptr<AccountList> accounts() const { return m_accounts; } - Status status() const - { + QString msaClientId() const; + + Status status() const { return m_status; } - const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const - { + const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const { return m_profilers; } + void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); + + shared_qobject_ptr<QNetworkAccessManager> network(); + + shared_qobject_ptr<HttpMetaCache> metacache(); + + shared_qobject_ptr<Meta::Index> metadataIndex(); + + QString getJarsPath(); + /// this is the root of the 'installation'. Used for automatic updates - const QString &root() - { + const QString &root() { return m_rootPath; } @@ -153,11 +150,11 @@ signals: public slots: bool launch( - InstancePtr instance, - bool online = true, - BaseProfilerFactory *profiler = nullptr, - MinecraftServerTargetPtr serverToJoin = nullptr, - MinecraftAccountPtr accountToUse = nullptr + InstancePtr instance, + bool online = true, + BaseProfilerFactory *profiler = nullptr, + MinecraftServerTargetPtr serverToJoin = nullptr, + MinecraftAccountPtr accountToUse = nullptr ); bool kill(InstancePtr instance); @@ -184,22 +181,29 @@ private: private: QDateTime startTime; + shared_qobject_ptr<QNetworkAccessManager> m_network; + + shared_qobject_ptr<UpdateChecker> m_updateChecker; + shared_qobject_ptr<AccountList> m_accounts; + + shared_qobject_ptr<HttpMetaCache> m_metacache; + shared_qobject_ptr<Meta::Index> m_metadataIndex; + std::shared_ptr<SettingsObject> m_settings; std::shared_ptr<InstanceList> m_instances; - FolderInstanceProvider * m_instanceFolder = nullptr; std::shared_ptr<IconList> m_icons; - std::shared_ptr<UpdateChecker> m_updateChecker; - std::shared_ptr<AccountList> m_accounts; std::shared_ptr<JavaInstallList> m_javalist; std::shared_ptr<TranslationsModel> m_translations; std::shared_ptr<GenericPageProvider> m_globalSettingsProvider; std::map<QString, std::unique_ptr<ITheme>> m_themes; std::unique_ptr<MCEditTool> m_mcedit; + QString m_jarsPath; + QSet<QString> m_features; QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers; QString m_rootPath; - Status m_status = Launcher::StartingUp; + Status m_status = Application::StartingUp; #if defined Q_OS_WIN32 // used on Windows to attach the standard IO streams @@ -207,8 +211,7 @@ private: #endif // FIXME: attach to instances instead. - struct InstanceXtras - { + struct InstanceXtras { InstanceWindow * window = nullptr; shared_qobject_ptr<LaunchController> controller; }; diff --git a/launcher/LauncherMessage.cpp b/launcher/ApplicationMessage.cpp index 4cc56e22..e22bf13c 100644 --- a/launcher/LauncherMessage.cpp +++ b/launcher/ApplicationMessage.cpp @@ -1,9 +1,9 @@ -#include "LauncherMessage.h" +#include "ApplicationMessage.h" #include <QJsonDocument> #include <QJsonObject> -void LauncherMessage::parse(const QByteArray & input) { +void ApplicationMessage::parse(const QByteArray & input) { auto doc = QJsonDocument::fromBinaryData(input); auto root = doc.object(); @@ -16,7 +16,7 @@ void LauncherMessage::parse(const QByteArray & input) { } } -QByteArray LauncherMessage::serialize() { +QByteArray ApplicationMessage::serialize() { QJsonObject root; root.insert("command", command); QJsonObject outArgs; diff --git a/launcher/LauncherMessage.h b/launcher/ApplicationMessage.h index 024b16a5..745bdead 100644 --- a/launcher/LauncherMessage.h +++ b/launcher/ApplicationMessage.h @@ -4,7 +4,7 @@ #include <QMap> #include <QByteArray> -struct LauncherMessage { +struct ApplicationMessage { QString command; QMap<QString, QString> args; diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 253d2130..fd26bb4f 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -143,7 +143,7 @@ public: virtual SettingsObjectPtr settings() const; /// returns a valid update task - virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0; + virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0; /// returns a valid launcher (task container) virtual shared_qobject_ptr<LaunchTask> createLaunchTask( diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h index ce7abce1..80a91e8f 100644 --- a/launcher/BaseVersionList.h +++ b/launcher/BaseVersionList.h @@ -63,7 +63,7 @@ public: * The task returned by this function should reset the model when it's done. * \return A pointer to a task that reloads the version list. */ - virtual shared_qobject_ptr<Task> getLoadTask() = 0; + virtual Task::Ptr getLoadTask() = 0; //! Checks whether or not the list is loaded. If this returns false, the list should be //loaded. diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index eba8f8a1..08c878d1 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -43,10 +43,6 @@ set(CORE_SOURCES # Prefix tree where node names are strings between separators SeparatorPrefixTree.h - # WARNING: globals live here - Env.h - Env.cpp - # String filters Filter.h Filter.cpp @@ -132,6 +128,8 @@ set(NET_SOURCES # Game launch logic set(LAUNCH_SOURCES + launch/steps/CheckJava.cpp + launch/steps/CheckJava.h launch/steps/LookupServerAddress.cpp launch/steps/LookupServerAddress.h launch/steps/PostLaunchCommand.cpp @@ -191,8 +189,6 @@ set(NEWS_SOURCES # Icon interface set(ICONS_SOURCES # Icons System and related code - icons/IIconList.h - icons/IIconList.cpp icons/IconUtils.h icons/IconUtils.cpp ) @@ -228,6 +224,9 @@ set(MINECRAFT_SOURCES minecraft/auth/flows/Yggdrasil.h minecraft/auth/flows/Yggdrasil.cpp + minecraft/auth/flows/Parsers.h + minecraft/auth/flows/Parsers.cpp + minecraft/gameoptions/GameOptions.h minecraft/gameoptions/GameOptions.cpp @@ -422,9 +421,6 @@ add_unit_test(INIFile ) set(JAVA_SOURCES - # Java related code - java/launch/CheckJava.cpp - java/launch/CheckJava.h java/JavaChecker.h java/JavaChecker.cpp java/JavaCheckerJob.h @@ -561,30 +557,37 @@ set(LOGIC_SOURCES SET(LAUNCHER_SOURCES # Application base - Launcher.h - Launcher.cpp + Application.h + Application.cpp UpdateController.cpp UpdateController.h - LauncherMessage.h - LauncherMessage.cpp + ApplicationMessage.h + ApplicationMessage.cpp # GUI - general utilities DesktopServices.h DesktopServices.cpp - GuiUtil.h - GuiUtil.cpp - ColumnResizer.h - ColumnResizer.cpp VersionProxyModel.h VersionProxyModel.cpp - ColorCache.h - ColorCache.cpp HoeDown.h # Super secret! KonamiCode.h KonamiCode.cpp + # Bundled resources + resources/backgrounds/backgrounds.qrc + resources/multimc/multimc.qrc + resources/pe_dark/pe_dark.qrc + resources/pe_light/pe_light.qrc + resources/pe_colored/pe_colored.qrc + resources/pe_blue/pe_blue.qrc + resources/OSX/OSX.qrc + resources/iOS/iOS.qrc + resources/flat/flat.qrc + resources/documents/documents.qrc + ../${Launcher_Branding_LogoQRC} + # Icons icons/MMCIcon.h icons/MMCIcon.cpp @@ -592,39 +595,43 @@ SET(LAUNCHER_SOURCES icons/IconList.cpp # GUI - windows - MainWindow.h - MainWindow.cpp - InstanceWindow.h - InstanceWindow.cpp + ui/GuiUtil.h + ui/GuiUtil.cpp + ui/ColorCache.h + ui/ColorCache.cpp + ui/MainWindow.h + ui/MainWindow.cpp + ui/InstanceWindow.h + ui/InstanceWindow.cpp # FIXME: maybe find a better home for this. SkinUtils.cpp SkinUtils.h # GUI - setup wizard - setupwizard/SetupWizard.h - setupwizard/SetupWizard.cpp - setupwizard/AnalyticsWizardPage.cpp - setupwizard/AnalyticsWizardPage.h - setupwizard/BaseWizardPage.h - setupwizard/JavaWizardPage.cpp - setupwizard/JavaWizardPage.h - setupwizard/LanguageWizardPage.cpp - setupwizard/LanguageWizardPage.h + ui/setupwizard/SetupWizard.h + ui/setupwizard/SetupWizard.cpp + ui/setupwizard/AnalyticsWizardPage.cpp + ui/setupwizard/AnalyticsWizardPage.h + ui/setupwizard/BaseWizardPage.h + ui/setupwizard/JavaWizardPage.cpp + ui/setupwizard/JavaWizardPage.h + ui/setupwizard/LanguageWizardPage.cpp + ui/setupwizard/LanguageWizardPage.h # GUI - themes - themes/FusionTheme.cpp - themes/FusionTheme.h - themes/BrightTheme.cpp - themes/BrightTheme.h - themes/CustomTheme.cpp - themes/CustomTheme.h - themes/DarkTheme.cpp - themes/DarkTheme.h - themes/ITheme.cpp - themes/ITheme.h - themes/SystemTheme.cpp - themes/SystemTheme.h + ui/themes/FusionTheme.cpp + ui/themes/FusionTheme.h + ui/themes/BrightTheme.cpp + ui/themes/BrightTheme.h + ui/themes/CustomTheme.cpp + ui/themes/CustomTheme.h + ui/themes/DarkTheme.cpp + ui/themes/DarkTheme.h + ui/themes/ITheme.cpp + ui/themes/ITheme.h + ui/themes/SystemTheme.cpp + ui/themes/SystemTheme.h # Processes LaunchController.h @@ -638,241 +645,233 @@ SET(LAUNCHER_SOURCES JavaCommon.cpp # GUI - paged dialog base - pages/BasePage.h - pages/BasePageContainer.h - pages/BasePageProvider.h + ui/pages/BasePage.h + ui/pages/BasePageContainer.h + ui/pages/BasePageProvider.h # GUI - instance pages - pages/instance/GameOptionsPage.cpp - pages/instance/GameOptionsPage.h - pages/instance/VersionPage.cpp - pages/instance/VersionPage.h - pages/instance/TexturePackPage.h - pages/instance/ResourcePackPage.h - pages/instance/ShaderPackPage.h - pages/instance/ModFolderPage.cpp - pages/instance/ModFolderPage.h - pages/instance/NotesPage.cpp - pages/instance/NotesPage.h - pages/instance/LogPage.cpp - pages/instance/LogPage.h - pages/instance/InstanceSettingsPage.cpp - pages/instance/InstanceSettingsPage.h - pages/instance/ScreenshotsPage.cpp - pages/instance/ScreenshotsPage.h - pages/instance/OtherLogsPage.cpp - pages/instance/OtherLogsPage.h - pages/instance/ServersPage.cpp - pages/instance/ServersPage.h - pages/instance/LegacyUpgradePage.cpp - pages/instance/LegacyUpgradePage.h - pages/instance/WorldListPage.cpp - pages/instance/WorldListPage.h + ui/pages/instance/GameOptionsPage.cpp + ui/pages/instance/GameOptionsPage.h + ui/pages/instance/VersionPage.cpp + ui/pages/instance/VersionPage.h + ui/pages/instance/TexturePackPage.h + ui/pages/instance/ResourcePackPage.h + ui/pages/instance/ShaderPackPage.h + ui/pages/instance/ModFolderPage.cpp + ui/pages/instance/ModFolderPage.h + ui/pages/instance/NotesPage.cpp + ui/pages/instance/NotesPage.h + ui/pages/instance/LogPage.cpp + ui/pages/instance/LogPage.h + ui/pages/instance/InstanceSettingsPage.cpp + ui/pages/instance/InstanceSettingsPage.h + ui/pages/instance/ScreenshotsPage.cpp + ui/pages/instance/ScreenshotsPage.h + ui/pages/instance/OtherLogsPage.cpp + ui/pages/instance/OtherLogsPage.h + ui/pages/instance/ServersPage.cpp + ui/pages/instance/ServersPage.h + ui/pages/instance/LegacyUpgradePage.cpp + ui/pages/instance/LegacyUpgradePage.h + ui/pages/instance/WorldListPage.cpp + ui/pages/instance/WorldListPage.h # GUI - global settings pages - pages/global/AccountListPage.cpp - pages/global/AccountListPage.h - pages/global/CustomCommandsPage.cpp - pages/global/CustomCommandsPage.h - pages/global/ExternalToolsPage.cpp - pages/global/ExternalToolsPage.h - pages/global/JavaPage.cpp - pages/global/JavaPage.h - pages/global/LanguagePage.cpp - pages/global/LanguagePage.h - pages/global/MinecraftPage.cpp - pages/global/MinecraftPage.h - pages/global/LauncherPage.cpp - pages/global/LauncherPage.h - pages/global/ProxyPage.cpp - pages/global/ProxyPage.h - pages/global/PasteEEPage.cpp - pages/global/PasteEEPage.h + ui/pages/global/AccountListPage.cpp + ui/pages/global/AccountListPage.h + ui/pages/global/CustomCommandsPage.cpp + ui/pages/global/CustomCommandsPage.h + ui/pages/global/ExternalToolsPage.cpp + ui/pages/global/ExternalToolsPage.h + ui/pages/global/JavaPage.cpp + ui/pages/global/JavaPage.h + ui/pages/global/LanguagePage.cpp + ui/pages/global/LanguagePage.h + ui/pages/global/MinecraftPage.cpp + ui/pages/global/MinecraftPage.h + ui/pages/global/LauncherPage.cpp + ui/pages/global/LauncherPage.h + ui/pages/global/ProxyPage.cpp + ui/pages/global/ProxyPage.h + ui/pages/global/PasteEEPage.cpp + ui/pages/global/PasteEEPage.h # GUI - platform pages - pages/modplatform/VanillaPage.cpp - pages/modplatform/VanillaPage.h - - pages/modplatform/atlauncher/AtlFilterModel.cpp - pages/modplatform/atlauncher/AtlFilterModel.h - pages/modplatform/atlauncher/AtlListModel.cpp - pages/modplatform/atlauncher/AtlListModel.h - pages/modplatform/atlauncher/AtlOptionalModDialog.cpp - pages/modplatform/atlauncher/AtlOptionalModDialog.h - pages/modplatform/atlauncher/AtlPage.cpp - pages/modplatform/atlauncher/AtlPage.h - - pages/modplatform/ftb/FtbFilterModel.cpp - pages/modplatform/ftb/FtbFilterModel.h - pages/modplatform/ftb/FtbListModel.cpp - pages/modplatform/ftb/FtbListModel.h - pages/modplatform/ftb/FtbPage.cpp - pages/modplatform/ftb/FtbPage.h - - pages/modplatform/legacy_ftb/Page.cpp - pages/modplatform/legacy_ftb/Page.h - pages/modplatform/legacy_ftb/ListModel.h - pages/modplatform/legacy_ftb/ListModel.cpp - - pages/modplatform/flame/FlameModel.cpp - pages/modplatform/flame/FlameModel.h - pages/modplatform/flame/FlamePage.cpp - pages/modplatform/flame/FlamePage.h - - pages/modplatform/technic/TechnicModel.cpp - pages/modplatform/technic/TechnicModel.h - pages/modplatform/technic/TechnicPage.cpp - pages/modplatform/technic/TechnicPage.h - - pages/modplatform/ImportPage.cpp - pages/modplatform/ImportPage.h + ui/pages/modplatform/VanillaPage.cpp + ui/pages/modplatform/VanillaPage.h + + ui/pages/modplatform/atlauncher/AtlFilterModel.cpp + ui/pages/modplatform/atlauncher/AtlFilterModel.h + ui/pages/modplatform/atlauncher/AtlListModel.cpp + ui/pages/modplatform/atlauncher/AtlListModel.h + ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp + ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h + ui/pages/modplatform/atlauncher/AtlPage.cpp + ui/pages/modplatform/atlauncher/AtlPage.h + + ui/pages/modplatform/ftb/FtbFilterModel.cpp + ui/pages/modplatform/ftb/FtbFilterModel.h + ui/pages/modplatform/ftb/FtbListModel.cpp + ui/pages/modplatform/ftb/FtbListModel.h + ui/pages/modplatform/ftb/FtbPage.cpp + ui/pages/modplatform/ftb/FtbPage.h + + ui/pages/modplatform/legacy_ftb/Page.cpp + ui/pages/modplatform/legacy_ftb/Page.h + ui/pages/modplatform/legacy_ftb/ListModel.h + ui/pages/modplatform/legacy_ftb/ListModel.cpp + + ui/pages/modplatform/flame/FlameModel.cpp + ui/pages/modplatform/flame/FlameModel.h + ui/pages/modplatform/flame/FlamePage.cpp + ui/pages/modplatform/flame/FlamePage.h + + ui/pages/modplatform/technic/TechnicModel.cpp + ui/pages/modplatform/technic/TechnicModel.h + ui/pages/modplatform/technic/TechnicPage.cpp + ui/pages/modplatform/technic/TechnicPage.h + + ui/pages/modplatform/ImportPage.cpp + ui/pages/modplatform/ImportPage.h # GUI - dialogs - dialogs/AboutDialog.cpp - dialogs/AboutDialog.h - dialogs/ProfileSelectDialog.cpp - dialogs/ProfileSelectDialog.h - dialogs/CopyInstanceDialog.cpp - dialogs/CopyInstanceDialog.h - dialogs/CustomMessageBox.cpp - dialogs/CustomMessageBox.h - dialogs/EditAccountDialog.cpp - dialogs/EditAccountDialog.h - dialogs/ExportInstanceDialog.cpp - dialogs/ExportInstanceDialog.h - dialogs/IconPickerDialog.cpp - dialogs/IconPickerDialog.h - dialogs/LoginDialog.cpp - dialogs/LoginDialog.h - dialogs/MSALoginDialog.cpp - dialogs/MSALoginDialog.h - dialogs/NewComponentDialog.cpp - dialogs/NewComponentDialog.h - dialogs/NewInstanceDialog.cpp - dialogs/NewInstanceDialog.h - dialogs/NotificationDialog.cpp - dialogs/NotificationDialog.h - pagedialog/PageDialog.cpp - pagedialog/PageDialog.h - dialogs/ProgressDialog.cpp - dialogs/ProgressDialog.h - dialogs/UpdateDialog.cpp - dialogs/UpdateDialog.h - dialogs/VersionSelectDialog.cpp - dialogs/VersionSelectDialog.h - dialogs/SkinUploadDialog.cpp - dialogs/SkinUploadDialog.h + ui/dialogs/AboutDialog.cpp + ui/dialogs/AboutDialog.h + ui/dialogs/ProfileSelectDialog.cpp + ui/dialogs/ProfileSelectDialog.h + ui/dialogs/ProfileSetupDialog.cpp + ui/dialogs/ProfileSetupDialog.h + ui/dialogs/CopyInstanceDialog.cpp + ui/dialogs/CopyInstanceDialog.h + ui/dialogs/CustomMessageBox.cpp + ui/dialogs/CustomMessageBox.h + ui/dialogs/EditAccountDialog.cpp + ui/dialogs/EditAccountDialog.h + ui/dialogs/ExportInstanceDialog.cpp + ui/dialogs/ExportInstanceDialog.h + ui/dialogs/IconPickerDialog.cpp + ui/dialogs/IconPickerDialog.h + ui/dialogs/LoginDialog.cpp + ui/dialogs/LoginDialog.h + ui/dialogs/MSALoginDialog.cpp + ui/dialogs/MSALoginDialog.h + ui/dialogs/NewComponentDialog.cpp + ui/dialogs/NewComponentDialog.h + ui/dialogs/NewInstanceDialog.cpp + ui/dialogs/NewInstanceDialog.h + ui/dialogs/NotificationDialog.cpp + ui/dialogs/NotificationDialog.h + ui/pagedialog/PageDialog.cpp + ui/pagedialog/PageDialog.h + ui/dialogs/ProgressDialog.cpp + ui/dialogs/ProgressDialog.h + ui/dialogs/UpdateDialog.cpp + ui/dialogs/UpdateDialog.h + ui/dialogs/VersionSelectDialog.cpp + ui/dialogs/VersionSelectDialog.h + ui/dialogs/SkinUploadDialog.cpp + ui/dialogs/SkinUploadDialog.h # GUI - widgets - widgets/Common.cpp - widgets/Common.h - widgets/CustomCommands.cpp - widgets/CustomCommands.h - widgets/DropLabel.cpp - widgets/DropLabel.h - widgets/FocusLineEdit.cpp - widgets/FocusLineEdit.h - widgets/IconLabel.cpp - widgets/IconLabel.h - widgets/JavaSettingsWidget.cpp - widgets/JavaSettingsWidget.h - widgets/LabeledToolButton.cpp - widgets/LabeledToolButton.h - widgets/LanguageSelectionWidget.cpp - widgets/LanguageSelectionWidget.h - widgets/LineSeparator.cpp - widgets/LineSeparator.h - widgets/LogView.cpp - widgets/LogView.h - widgets/MCModInfoFrame.cpp - widgets/MCModInfoFrame.h - widgets/ModListView.cpp - widgets/ModListView.h - widgets/PageContainer.cpp - widgets/PageContainer.h - widgets/PageContainer_p.h - widgets/VersionListView.cpp - widgets/VersionListView.h - widgets/VersionSelectWidget.cpp - widgets/VersionSelectWidget.h - widgets/ProgressWidget.h - widgets/ProgressWidget.cpp - widgets/WideBar.h - widgets/WideBar.cpp + ui/widgets/Common.cpp + ui/widgets/Common.h + ui/widgets/CustomCommands.cpp + ui/widgets/CustomCommands.h + ui/widgets/DropLabel.cpp + ui/widgets/DropLabel.h + ui/widgets/FocusLineEdit.cpp + ui/widgets/FocusLineEdit.h + ui/widgets/IconLabel.cpp + ui/widgets/IconLabel.h + ui/widgets/JavaSettingsWidget.cpp + ui/widgets/JavaSettingsWidget.h + ui/widgets/LabeledToolButton.cpp + ui/widgets/LabeledToolButton.h + ui/widgets/LanguageSelectionWidget.cpp + ui/widgets/LanguageSelectionWidget.h + ui/widgets/LineSeparator.cpp + ui/widgets/LineSeparator.h + ui/widgets/LogView.cpp + ui/widgets/LogView.h + ui/widgets/MCModInfoFrame.cpp + ui/widgets/MCModInfoFrame.h + ui/widgets/ModListView.cpp + ui/widgets/ModListView.h + ui/widgets/PageContainer.cpp + ui/widgets/PageContainer.h + ui/widgets/PageContainer_p.h + ui/widgets/VersionListView.cpp + ui/widgets/VersionListView.h + ui/widgets/VersionSelectWidget.cpp + ui/widgets/VersionSelectWidget.h + ui/widgets/ProgressWidget.h + ui/widgets/ProgressWidget.cpp + ui/widgets/WideBar.h + ui/widgets/WideBar.cpp # GUI - instance group view - instanceview/InstanceProxyModel.cpp - instanceview/InstanceProxyModel.h - instanceview/AccessibleInstanceView.cpp - instanceview/AccessibleInstanceView.h - instanceview/AccessibleInstanceView_p.h - instanceview/InstanceView.cpp - instanceview/InstanceView.h - instanceview/InstanceDelegate.cpp - instanceview/InstanceDelegate.h - instanceview/VisualGroup.cpp - instanceview/VisualGroup.h - ) + ui/instanceview/InstanceProxyModel.cpp + ui/instanceview/InstanceProxyModel.h + ui/instanceview/AccessibleInstanceView.cpp + ui/instanceview/AccessibleInstanceView.h + ui/instanceview/AccessibleInstanceView_p.h + ui/instanceview/InstanceView.cpp + ui/instanceview/InstanceView.h + ui/instanceview/InstanceDelegate.cpp + ui/instanceview/InstanceDelegate.h + ui/instanceview/VisualGroup.cpp + ui/instanceview/VisualGroup.h +) -######## UIs ######## -SET(LAUNCHER_UIS - # Instance pages - pages/instance/GameOptionsPage.ui - pages/instance/VersionPage.ui - pages/instance/ModFolderPage.ui - pages/instance/LogPage.ui - pages/instance/InstanceSettingsPage.ui - pages/instance/NotesPage.ui - pages/instance/ScreenshotsPage.ui - pages/instance/OtherLogsPage.ui - pages/instance/LegacyUpgradePage.ui - pages/instance/ServersPage.ui - pages/instance/WorldListPage.ui - - # Global settings pages - pages/global/AccountListPage.ui - pages/global/ExternalToolsPage.ui - pages/global/JavaPage.ui - pages/global/MinecraftPage.ui - pages/global/LauncherPage.ui - pages/global/ProxyPage.ui - pages/global/PasteEEPage.ui - - # Platform pages - pages/modplatform/VanillaPage.ui - pages/modplatform/atlauncher/AtlPage.ui - pages/modplatform/ftb/FtbPage.ui - pages/modplatform/legacy_ftb/Page.ui - pages/modplatform/flame/FlamePage.ui - pages/modplatform/technic/TechnicPage.ui - pages/modplatform/ImportPage.ui - - # Platform Dialogs - pages/modplatform/atlauncher/AtlOptionalModDialog.ui - - # Dialogs - dialogs/CopyInstanceDialog.ui - dialogs/NewComponentDialog.ui - dialogs/NewInstanceDialog.ui - dialogs/AboutDialog.ui - dialogs/ProgressDialog.ui - dialogs/IconPickerDialog.ui - dialogs/ProfileSelectDialog.ui - dialogs/EditAccountDialog.ui - dialogs/ExportInstanceDialog.ui - dialogs/LoginDialog.ui - dialogs/MSALoginDialog.ui - dialogs/UpdateDialog.ui - dialogs/NotificationDialog.ui - dialogs/SkinUploadDialog.ui - - # Widgets/other - widgets/CustomCommands.ui - widgets/MCModInfoFrame.ui +qt5_wrap_ui(LAUNCHER_UI + ui/pages/global/AccountListPage.ui + ui/pages/global/JavaPage.ui + ui/pages/global/LauncherPage.ui + ui/pages/global/PasteEEPage.ui + ui/pages/global/ProxyPage.ui + ui/pages/global/MinecraftPage.ui + ui/pages/global/ExternalToolsPage.ui + ui/pages/instance/ModFolderPage.ui + ui/pages/instance/NotesPage.ui + ui/pages/instance/LogPage.ui + ui/pages/instance/ServersPage.ui + ui/pages/instance/GameOptionsPage.ui + ui/pages/instance/OtherLogsPage.ui + ui/pages/instance/InstanceSettingsPage.ui + ui/pages/instance/VersionPage.ui + ui/pages/instance/WorldListPage.ui + ui/pages/instance/LegacyUpgradePage.ui + ui/pages/instance/ScreenshotsPage.ui + ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui + ui/pages/modplatform/atlauncher/AtlPage.ui + ui/pages/modplatform/VanillaPage.ui + ui/pages/modplatform/flame/FlamePage.ui + ui/pages/modplatform/legacy_ftb/Page.ui + ui/pages/modplatform/ImportPage.ui + ui/pages/modplatform/ftb/FtbPage.ui + ui/pages/modplatform/technic/TechnicPage.ui + ui/widgets/InstanceCardWidget.ui + ui/widgets/CustomCommands.ui + ui/widgets/MCModInfoFrame.ui + ui/dialogs/CopyInstanceDialog.ui + ui/dialogs/ProfileSetupDialog.ui + ui/dialogs/ProgressDialog.ui + ui/dialogs/NewInstanceDialog.ui + ui/dialogs/NotificationDialog.ui + ui/dialogs/UpdateDialog.ui + ui/dialogs/NewComponentDialog.ui + ui/dialogs/ProfileSelectDialog.ui + ui/dialogs/SkinUploadDialog.ui + ui/dialogs/ExportInstanceDialog.ui + ui/dialogs/IconPickerDialog.ui + ui/dialogs/MSALoginDialog.ui + ui/dialogs/AboutDialog.ui + ui/dialogs/LoginDialog.ui + ui/dialogs/EditAccountDialog.ui ) -set(LAUNCHER_QRCS +qt5_add_resources(LAUNCHER_RESOURCES resources/backgrounds/backgrounds.qrc resources/multimc/multimc.qrc resources/pe_dark/pe_dark.qrc @@ -891,10 +890,6 @@ if(WIN32) set(LAUNCHER_RCS ../${Launcher_Branding_WindowsRC}) endif() -# Qt 5 stuff -qt5_wrap_ui(LAUNCHER_UI ${LAUNCHER_UIS}) -qt5_add_resources(LAUNCHER_RESOURCES ${LAUNCHER_QRCS}) - # Add executable add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES}) target_link_libraries(Launcher_logic diff --git a/launcher/ColumnResizer.cpp b/launcher/ColumnResizer.cpp deleted file mode 100644 index fe415067..00000000 --- a/launcher/ColumnResizer.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -* Copyright 2011 Aurélien Gâteau <agateau@kde.org> -* License: BSD-3-Clause -*/ -#include <ColumnResizer.h> - -#include <QDebug> -#include <QEvent> -#include <QFormLayout> -#include <QGridLayout> -#include <QTimer> -#include <QWidget> - -class FormLayoutWidgetItem : public QWidgetItem -{ -public: - FormLayoutWidgetItem(QWidget* widget, QFormLayout* formLayout, QFormLayout::ItemRole itemRole) - : QWidgetItem(widget) - , m_width(-1) - , m_formLayout(formLayout) - , m_itemRole(itemRole) - {} - - QSize sizeHint() const - { - QSize size = QWidgetItem::sizeHint(); - if (m_width != -1) { - size.setWidth(m_width); - } - return size; - } - - QSize minimumSize() const - { - QSize size = QWidgetItem::minimumSize(); - if (m_width != -1) { - size.setWidth(m_width); - } - return size; - } - - QSize maximumSize() const - { - QSize size = QWidgetItem::maximumSize(); - if (m_width != -1) { - size.setWidth(m_width); - } - return size; - } - - void setWidth(int width) - { - if (width != m_width) { - m_width = width; - invalidate(); - } - } - - void setGeometry(const QRect& _rect) - { - QRect rect = _rect; - int width = widget()->sizeHint().width(); - if (m_itemRole == QFormLayout::LabelRole && m_formLayout->labelAlignment() & Qt::AlignRight) { - rect.setLeft(rect.right() - width); - } - QWidgetItem::setGeometry(rect); - } - - QFormLayout* formLayout() const - { - return m_formLayout; - } - -private: - int m_width; - QFormLayout* m_formLayout; - QFormLayout::ItemRole m_itemRole; -}; - -typedef QPair<QGridLayout*, int> GridColumnInfo; - -class ColumnResizerPrivate -{ -public: - ColumnResizerPrivate(ColumnResizer* q_ptr) - : q(q_ptr) - , m_updateTimer(new QTimer(q)) - { - m_updateTimer->setSingleShot(true); - m_updateTimer->setInterval(0); - QObject::connect(m_updateTimer, SIGNAL(timeout()), q, SLOT(updateWidth())); - } - - void scheduleWidthUpdate() - { - m_updateTimer->start(); - } - - ColumnResizer* q; - QTimer* m_updateTimer; - QList<QWidget*> m_widgets; - QList<FormLayoutWidgetItem*> m_wrWidgetItemList; - QList<GridColumnInfo> m_gridColumnInfoList; -}; - -ColumnResizer::ColumnResizer(QObject* parent) -: QObject(parent) -, d(new ColumnResizerPrivate(this)) -{} - -ColumnResizer::~ColumnResizer() -{ - delete d; -} - -void ColumnResizer::addWidget(QWidget* widget) -{ - d->m_widgets.append(widget); - widget->installEventFilter(this); - d->scheduleWidthUpdate(); -} - -void ColumnResizer::updateWidth() -{ - int width = 0; - Q_FOREACH(QWidget* widget, d->m_widgets) { - width = qMax(widget->sizeHint().width(), width); - } - Q_FOREACH(FormLayoutWidgetItem* item, d->m_wrWidgetItemList) { - item->setWidth(width); - item->formLayout()->update(); - } - Q_FOREACH(GridColumnInfo info, d->m_gridColumnInfoList) { - info.first->setColumnMinimumWidth(info.second, width); - } -} - -bool ColumnResizer::eventFilter(QObject*, QEvent* event) -{ - if (event->type() == QEvent::Resize) { - d->scheduleWidthUpdate(); - } - return false; -} - -void ColumnResizer::addWidgetsFromLayout(QLayout* layout, int column) -{ - Q_ASSERT(column >= 0); - QGridLayout* gridLayout = qobject_cast<QGridLayout*>(layout); - QFormLayout* formLayout = qobject_cast<QFormLayout*>(layout); - if (gridLayout) { - addWidgetsFromGridLayout(gridLayout, column); - } else if (formLayout) { - if (column > QFormLayout::SpanningRole) { - qCritical() << "column should not be more than" << QFormLayout::SpanningRole << "for QFormLayout"; - return; - } - QFormLayout::ItemRole role = static_cast<QFormLayout::ItemRole>(column); - addWidgetsFromFormLayout(formLayout, role); - } else { - qCritical() << "Don't know how to handle layout" << layout; - } -} - -void ColumnResizer::addWidgetsFromGridLayout(QGridLayout* layout, int column) -{ - for (int row = 0; row < layout->rowCount(); ++row) { - QLayoutItem* item = layout->itemAtPosition(row, column); - if (!item) { - continue; - } - QWidget* widget = item->widget(); - if (!widget) { - continue; - } - addWidget(widget); - } - d->m_gridColumnInfoList << GridColumnInfo(layout, column); -} - -void ColumnResizer::addWidgetsFromFormLayout(QFormLayout* layout, QFormLayout::ItemRole role) -{ - for (int row = 0; row < layout->rowCount(); ++row) { - QLayoutItem* item = layout->itemAt(row, role); - if (!item) { - continue; - } - QWidget* widget = item->widget(); - if (!widget) { - continue; - } - layout->removeItem(item); - delete item; - FormLayoutWidgetItem* newItem = new FormLayoutWidgetItem(widget, layout, role); - layout->setItem(row, role, newItem); - addWidget(widget); - d->m_wrWidgetItemList << newItem; - } -} diff --git a/launcher/ColumnResizer.h b/launcher/ColumnResizer.h deleted file mode 100644 index 8c920f01..00000000 --- a/launcher/ColumnResizer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright 2011 Aurélien Gâteau <agateau@kde.org> -* License: BSD-3-Clause -*/ -#ifndef COLUMNRESIZER_H -#define COLUMNRESIZER_H - -#include <QFormLayout> - -#include <QtCore/QObject> -#include <QtCore/QList> - -class QEvent; -class QGridLayout; -class QLayout; -class QWidget; - -class ColumnResizerPrivate; -class ColumnResizer : public QObject -{ - Q_OBJECT -public: - ColumnResizer(QObject* parent = 0); - ~ColumnResizer(); - - void addWidget(QWidget* widget); - void addWidgetsFromLayout(QLayout*, int column); - void addWidgetsFromGridLayout(QGridLayout*, int column); - void addWidgetsFromFormLayout(QFormLayout*, QFormLayout::ItemRole role); - -private Q_SLOTS: - void updateWidth(); - -protected: - bool eventFilter(QObject*, QEvent* event); - -private: - ColumnResizerPrivate* const d; -}; - -#endif /* COLUMNRESIZER_H */ diff --git a/launcher/Env.cpp b/launcher/Env.cpp deleted file mode 100644 index abf9f58c..00000000 --- a/launcher/Env.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "Env.h" -#include "net/HttpMetaCache.h" -#include "BaseVersion.h" -#include "BaseVersionList.h" -#include <QDir> -#include <QCoreApplication> -#include <QNetworkProxy> -#include <QNetworkAccessManager> -#include <QDebug> -#include "tasks/Task.h" -#include "meta/Index.h" -#include "FileSystem.h" -#include <QDebug> - - -struct Env::Private -{ - QNetworkAccessManager m_qnam; - shared_qobject_ptr<HttpMetaCache> m_metacache; - std::shared_ptr<IIconList> m_iconlist; - shared_qobject_ptr<Meta::Index> m_metadataIndex; - QString m_jarsPath; - QSet<QString> m_features; -}; - -static Env * instance; - -/* - * The *NEW* global rat nest of an object. Handle with care. - */ - -Env::Env() -{ - d = new Private(); -} - -Env::~Env() -{ - delete d; -} - -Env& Env::Env::getInstance() -{ - if(!instance) - { - instance = new Env(); - } - return *instance; -} - -void Env::dispose() -{ - delete instance; - instance = nullptr; -} - -shared_qobject_ptr< HttpMetaCache > Env::metacache() -{ - return d->m_metacache; -} - -QNetworkAccessManager& Env::qnam() const -{ - return d->m_qnam; -} - -std::shared_ptr<IIconList> Env::icons() -{ - return d->m_iconlist; -} - -void Env::registerIconList(std::shared_ptr<IIconList> iconlist) -{ - d->m_iconlist = iconlist; -} - -shared_qobject_ptr<Meta::Index> Env::metadataIndex() -{ - if (!d->m_metadataIndex) - { - d->m_metadataIndex.reset(new Meta::Index()); - } - return d->m_metadataIndex; -} - - -void Env::initHttpMetaCache() -{ - auto &m_metacache = d->m_metacache; - m_metacache.reset(new HttpMetaCache("metacache")); - m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath()); - m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath()); - m_metacache->addBase("versions", QDir("versions").absolutePath()); - m_metacache->addBase("libraries", QDir("libraries").absolutePath()); - m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath()); - m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath()); - m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); - m_metacache->addBase("general", QDir("cache").absolutePath()); - m_metacache->addBase("ATLauncherPacks", QDir("cache/ATLauncherPacks").absolutePath()); - m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath()); - m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath()); - m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath()); - m_metacache->addBase("FlamePacks", QDir("cache/FlamePacks").absolutePath()); - m_metacache->addBase("root", QDir::currentPath()); - m_metacache->addBase("translations", QDir("translations").absolutePath()); - m_metacache->addBase("icons", QDir("cache/icons").absolutePath()); - m_metacache->addBase("meta", QDir("meta").absolutePath()); - m_metacache->Load(); -} - -void Env::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password) -{ - // Set the application proxy settings. - if (proxyTypeStr == "SOCKS5") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); - } - else if (proxyTypeStr == "HTTP") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password)); - } - else if (proxyTypeStr == "None") - { - // If we have no proxy set, set no proxy and return. - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); - } - else - { - // If we have "Default" selected, set Qt to use the system proxy settings. - QNetworkProxyFactory::setUseSystemConfiguration(true); - } - - qDebug() << "Detecting proxy settings..."; - QNetworkProxy proxy = QNetworkProxy::applicationProxy(); - d->m_qnam.setProxy(proxy); - QString proxyDesc; - if (proxy.type() == QNetworkProxy::NoProxy) - { - qDebug() << "Using no proxy is an option!"; - return; - } - switch (proxy.type()) - { - case QNetworkProxy::DefaultProxy: - proxyDesc = "Default proxy: "; - break; - case QNetworkProxy::Socks5Proxy: - proxyDesc = "Socks5 proxy: "; - break; - case QNetworkProxy::HttpProxy: - proxyDesc = "HTTP proxy: "; - break; - case QNetworkProxy::HttpCachingProxy: - proxyDesc = "HTTP caching: "; - break; - case QNetworkProxy::FtpCachingProxy: - proxyDesc = "FTP caching: "; - break; - default: - proxyDesc = "DERP proxy: "; - break; - } - proxyDesc += QString("%1:%2") - .arg(proxy.hostName()) - .arg(proxy.port()); - qDebug() << proxyDesc; -} - -QString Env::getJarsPath() -{ - if(d->m_jarsPath.isEmpty()) - { - return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars"); - } - return d->m_jarsPath; -} - -void Env::setJarsPath(const QString& path) -{ - d->m_jarsPath = path; -} - -void Env::enableFeature(const QString& featureName, bool state) -{ - if(state) - { - d->m_features.insert(featureName); - } - else - { - d->m_features.remove(featureName); - } -} - -bool Env::isFeatureEnabled(const QString& featureName) const -{ - return d->m_features.contains(featureName); -} - -void Env::getEnabledFeatures(QSet<QString>& features) const -{ - features = d->m_features; -} - -void Env::setEnabledFeatures(const QSet<QString>& features) const -{ - d->m_features = features; -} diff --git a/launcher/Env.h b/launcher/Env.h deleted file mode 100644 index 52427696..00000000 --- a/launcher/Env.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include <memory> -#include "icons/IIconList.h" -#include <QString> -#include <QMap> - -#include "QObjectPtr.h" - -class QNetworkAccessManager; -class HttpMetaCache; -class BaseVersionList; -class BaseVersion; - -namespace Meta -{ -class Index; -} - -#if defined(ENV) - #undef ENV -#endif -#define ENV (Env::getInstance()) - - -class Env -{ - friend class Launcher; -private: - struct Private; - Env(); - ~Env(); - static void dispose(); -public: - static Env& getInstance(); - - QNetworkAccessManager &qnam() const; - - shared_qobject_ptr<HttpMetaCache> metacache(); - - std::shared_ptr<IIconList> icons(); - - /// init the cache. FIXME: possible future hook point - void initHttpMetaCache(); - - /// Updates the application proxy settings from the settings object. - void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); - - void registerIconList(std::shared_ptr<IIconList> iconlist); - - shared_qobject_ptr<Meta::Index> metadataIndex(); - - QString getJarsPath(); - void setJarsPath(const QString & path); - - bool isFeatureEnabled(const QString & featureName) const; - void enableFeature(const QString & featureName, bool state = true); - void getEnabledFeatures(QSet<QString> & features) const; - void setEnabledFeatures(const QSet<QString> & features) const; - -protected: - Private * d; -}; diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 3eac4d57..d0a63fe3 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -16,11 +16,10 @@ #include "InstanceImportTask.h" #include "BaseInstance.h" #include "FileSystem.h" -#include "Env.h" +#include "Application.h" #include "MMCZip.h" #include "NullInstance.h" #include "settings/INISettingsObject.h" -#include "icons/IIconList.h" #include "icons/IconUtils.h" #include <QtConcurrentRun> @@ -33,6 +32,9 @@ #include <quazipdir.h> #include "modplatform/technic/TechnicPackProcessor.h" +#include "icons/IconList.h" +#include "Application.h" + InstanceImportTask::InstanceImportTask(const QUrl sourceUrl) { m_sourceUrl = sourceUrl; @@ -51,7 +53,7 @@ void InstanceImportTask::executeTask() m_downloadRequired = true; const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path(); - auto entry = ENV.metacache()->resolveEntry("general", path); + auto entry = APPLICATION->metacache()->resolveEntry("general", path); entry->setStale(true); m_filesNetJob.reset(new NetJob(tr("Modpack download"))); m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); @@ -60,7 +62,7 @@ void InstanceImportTask::executeTask() connect(job, &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded); connect(job, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); connect(job, &NetJob::failed, this, &InstanceImportTask::downloadFailed); - m_filesNetJob->start(); + m_filesNetJob->start(APPLICATION->network()); } } @@ -331,7 +333,7 @@ void InstanceImportTask::processFlame() FS::deletePath(jarmodsPath); } instance.setName(m_instName); - m_modIdResolver.reset(new Flame::FileResolvingTask(pack)); + m_modIdResolver = new Flame::FileResolvingTask(APPLICATION->network(), pack); connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, [&]() { auto results = m_modIdResolver->getResults(); @@ -389,7 +391,7 @@ void InstanceImportTask::processFlame() setProgress(current, total); }); setStatus(tr("Downloading mods...")); - m_filesNetJob->start(); + m_filesNetJob->start(APPLICATION->network()); } ); connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [&](QString reason) @@ -418,7 +420,6 @@ void InstanceImportTask::processTechnic() void InstanceImportTask::processMultiMC() { - // FIXME: copy from FolderInstanceProvider!!! FIX IT!!! QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg"); auto instanceSettings = std::make_shared<INISettingsObject>(configPath); instanceSettings->registerSetting("InstanceType", "Legacy"); @@ -444,7 +445,7 @@ void InstanceImportTask::processMultiMC() if (!importIconPath.isNull() && QFile::exists(importIconPath)) { // import icon - auto iconList = ENV.icons(); + auto iconList = APPLICATION->icons(); if (iconList->iconFileExists(m_instIcon)) { iconList->deleteIcon(m_instIcon); diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index 72ae6851..a1990647 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -55,7 +55,7 @@ private slots: void extractAborted(); private: /* data */ - NetJobPtr m_filesNetJob; + NetJob::Ptr m_filesNetJob; shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver; QUrl m_sourceUrl; QString m_archivePath; diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index d45b3f2e..2af90b91 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -2,24 +2,22 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/legacy/LegacyInstance.h" #include <FileSystem.h> -#include "pages/BasePage.h" -#include "pages/BasePageProvider.h" -#include "pages/instance/LogPage.h" -#include "pages/instance/VersionPage.h" -#include "pages/instance/ModFolderPage.h" -#include "pages/instance/ResourcePackPage.h" -#include "pages/instance/TexturePackPage.h" -#include "pages/instance/ShaderPackPage.h" -#include "pages/instance/NotesPage.h" -#include "pages/instance/ScreenshotsPage.h" -#include "pages/instance/InstanceSettingsPage.h" -#include "pages/instance/OtherLogsPage.h" -#include "pages/instance/LegacyUpgradePage.h" -#include "pages/instance/WorldListPage.h" -#include "pages/instance/ServersPage.h" -#include "pages/instance/GameOptionsPage.h" - -#include "Env.h" +#include "ui/pages/BasePage.h" +#include "ui/pages/BasePageProvider.h" +#include "ui/pages/instance/LogPage.h" +#include "ui/pages/instance/VersionPage.h" +#include "ui/pages/instance/ModFolderPage.h" +#include "ui/pages/instance/ResourcePackPage.h" +#include "ui/pages/instance/TexturePackPage.h" +#include "ui/pages/instance/ShaderPackPage.h" +#include "ui/pages/instance/NotesPage.h" +#include "ui/pages/instance/ScreenshotsPage.h" +#include "ui/pages/instance/InstanceSettingsPage.h" +#include "ui/pages/instance/OtherLogsPage.h" +#include "ui/pages/instance/LegacyUpgradePage.h" +#include "ui/pages/instance/WorldListPage.h" +#include "ui/pages/instance/ServersPage.h" +#include "ui/pages/instance/GameOptionsPage.h" class InstancePageProvider : public QObject, public BasePageProvider { diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index 92a058f0..6fa5851b 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -1,5 +1,5 @@ #include "JavaCommon.h" -#include "dialogs/CustomMessageBox.h" +#include "ui/dialogs/CustomMessageBox.h" #include <MMCStrings.h> bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 1c1e41e6..8bd5732f 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -1,24 +1,28 @@ #include "LaunchController.h" -#include "MainWindow.h" -#include <minecraft/auth/AccountList.h> -#include "Launcher.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/ProfileSelectDialog.h" -#include "dialogs/ProgressDialog.h" -#include "dialogs/EditAccountDialog.h" -#include "InstanceWindow.h" -#include "BuildConfig.h" -#include "JavaCommon.h" +#include "minecraft/auth/AccountList.h" +#include "Application.h" + +#include "ui/MainWindow.h" +#include "ui/InstanceWindow.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProfileSelectDialog.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/EditAccountDialog.h" +#include "ui/dialogs/ProfileSetupDialog.h" + #include <QLineEdit> #include <QInputDialog> -#include <tasks/Task.h> -#include <minecraft/auth/AccountTask.h> -#include <launch/steps/TextPrint.h> #include <QStringList> #include <QHostInfo> #include <QList> #include <QHostAddress> +#include "BuildConfig.h" +#include "JavaCommon.h" +#include "tasks/Task.h" +#include "minecraft/auth/AccountTask.h" +#include "launch/steps/TextPrint.h" + LaunchController::LaunchController(QObject *parent) : Task(parent) { } @@ -41,7 +45,7 @@ void LaunchController::decideAccount() } // Find an account to use. - std::shared_ptr<AccountList> accounts = LAUNCHER->accounts(); + auto accounts = APPLICATION->accounts(); if (accounts->count() <= 0) { // Tell the user they need to log in at least one account in order to play. @@ -58,12 +62,12 @@ void LaunchController::decideAccount() if (reply == QMessageBox::Yes) { // Open the account manager. - LAUNCHER->ShowGlobalSettings(m_parentWidget, "accounts"); + APPLICATION->ShowGlobalSettings(m_parentWidget, "accounts"); } } - m_accountToUse = accounts->activeAccount(); - if (m_accountToUse == nullptr) + m_accountToUse = accounts->defaultAccount(); + if (!m_accountToUse) { // If no default account is set, ask the user which one to use. ProfileSelectDialog selectDialog( @@ -79,7 +83,7 @@ void LaunchController::decideAccount() // If the user said to use the account as default, do that. if (selectDialog.useAsGlobalDefault() && m_accountToUse) { - accounts->setActiveAccount(m_accountToUse->profileId()); + accounts->setDefaultAccount(m_accountToUse); } } } @@ -109,7 +113,7 @@ void LaunchController::login() { { m_session = std::make_shared<AuthSession>(); m_session->wants_online = m_online; - std::shared_ptr<AccountTask> task; + shared_qobject_ptr<AccountTask> task; if(!password.isNull()) { task = m_accountToUse->login(m_session, password); } @@ -179,10 +183,40 @@ void LaunchController::login() { } break; } + case AuthSession::RequiresProfileSetup: { + auto entitlement = m_accountToUse->accountData()->minecraftEntitlement; + QString errorString; + if(!entitlement.canPlayMinecraft) { + errorString = tr("The account does not own Minecraft. You need to purchase the game first to play it."); + QMessageBox::warning( + nullptr, + tr("Missing Minecraft profile"), + errorString, + QMessageBox::StandardButton::Ok, + QMessageBox::StandardButton::Ok + ); + tryagain = false; + emitFailed(errorString); + return; + } + // Now handle setting up a profile name here... + ProfileSetupDialog dialog(m_accountToUse, m_parentWidget); + if (dialog.exec() == QDialog::Accepted) + { + tryagain = true; + continue; + } + else + { + tryagain = false; + emitFailed(tr("Received undetermined session status during login.")); + return; + } + } case AuthSession::RequiresOAuth: { auto errorString = tr("Microsoft account has expired and needs to be logged into manually again."); QMessageBox::warning( - nullptr, + m_parentWidget, tr("Microsoft Account refresh failed"), errorString, QMessageBox::StandardButton::Ok, @@ -195,7 +229,7 @@ void LaunchController::login() { case AuthSession::GoneOrMigrated: { auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to."); QMessageBox::warning( - nullptr, + m_parentWidget, tr("Account gone"), errorString, QMessageBox::StandardButton::Ok, @@ -263,7 +297,7 @@ void LaunchController::launchInstance() auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); if(!console && showConsole) { - LAUNCHER->showInstanceWindow(m_instance); + APPLICATION->showInstanceWindow(m_instance); } connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded); @@ -369,7 +403,7 @@ void LaunchController::onFailed(QString reason) { if(m_instance->settings()->get("ShowConsoleOnError").toBool()) { - LAUNCHER->showInstanceWindow(m_instance, "console"); + APPLICATION->showInstanceWindow(m_instance, "console"); } emitFailed(reason); } diff --git a/launcher/QObjectPtr.h b/launcher/QObjectPtr.h index 0ff51136..57974939 100644 --- a/launcher/QObjectPtr.h +++ b/launcher/QObjectPtr.h @@ -77,6 +77,12 @@ public: { return m_ptr; } + bool operator==(const shared_qobject_ptr<T>& other) { + return m_ptr == other.m_ptr; + } + bool operator!=(const shared_qobject_ptr<T>& other) { + return m_ptr != other.m_ptr; + } private: std::shared_ptr <T> m_ptr; diff --git a/launcher/SkinUtils.cpp b/launcher/SkinUtils.cpp index a196173e..1fe0c896 100644 --- a/launcher/SkinUtils.cpp +++ b/launcher/SkinUtils.cpp @@ -15,7 +15,7 @@ #include "SkinUtils.h" #include "net/HttpMetaCache.h" -#include "Env.h" +#include "Application.h" #include <QFile> #include <QPainter> @@ -30,7 +30,7 @@ namespace SkinUtils */ QPixmap getFaceFromCache(QString username, int height, int width) { - QFile fskin(ENV.metacache()->resolveEntry("skins", username + ".png")->getFullPath()); + QFile fskin(APPLICATION->metacache()->resolveEntry("skins", username + ".png")->getFullPath()); if (fskin.exists()) { diff --git a/launcher/Usable.h b/launcher/Usable.h index 83dd083d..a3e880f3 100644 --- a/launcher/Usable.h +++ b/launcher/Usable.h @@ -3,6 +3,8 @@ #include <cstddef> #include <memory> +#include "QObjectPtr.h" + class Usable; /** @@ -14,11 +16,11 @@ class Usable { friend class UseLock; public: - std::size_t useCount() + std::size_t useCount() const { return m_useCount; } - bool isInUse() + bool isInUse() const { return m_useCount > 0; } @@ -43,7 +45,7 @@ private: class UseLock { public: - UseLock(std::shared_ptr<Usable> usable) + UseLock(shared_qobject_ptr<Usable> usable) : m_usable(usable) { // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate. @@ -54,5 +56,5 @@ public: m_usable->decrementUses(); } private: - std::shared_ptr<Usable> m_usable; + shared_qobject_ptr<Usable> m_usable; }; diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 12f9bdd8..b9a87c9c 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,5 +1,5 @@ #include "VersionProxyModel.h" -#include "Launcher.h" +#include "Application.h" #include <QSortFilterProxyModel> #include <QPixmapCache> #include <Version.h> @@ -194,19 +194,19 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); if(value.toBool()) { - return LAUNCHER->getThemedIcon("star"); + return APPLICATION->getThemedIcon("star"); } else if(hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); if(value.toBool()) { - return LAUNCHER->getThemedIcon("bug"); + return APPLICATION->getThemedIcon("bug"); } } else if(index.row() == 0) { - return LAUNCHER->getThemedIcon("bug"); + return APPLICATION->getThemedIcon("bug"); } auto pixmap = QPixmapCache::find("placeholder"); if(!pixmap) diff --git a/launcher/icons/IIconList.cpp b/launcher/icons/IIconList.cpp deleted file mode 100644 index b3a8fb43..00000000 --- a/launcher/icons/IIconList.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "IIconList.h" - -// blargh -IIconList::~IIconList() -{ -} - diff --git a/launcher/icons/IIconList.h b/launcher/icons/IIconList.h deleted file mode 100644 index 15d7dd15..00000000 --- a/launcher/icons/IIconList.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <QString> -#include <QStringList> - -enum IconType : unsigned -{ - Builtin, - Transient, - FileBased, - ICONS_TOTAL, - ToBeDeleted -}; - -class IIconList -{ -public: - virtual ~IIconList(); - virtual bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) = 0; - virtual bool deleteIcon(const QString &key) = 0; - virtual void saveIcon(const QString &key, const QString &path, const char * format) const = 0; - virtual bool iconFileExists(const QString &key) const = 0; - virtual void installIcons(const QStringList &iconFiles) = 0; - virtual void installIcon(const QString &file, const QString &name) = 0; -}; diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h index 70266ebb..ebbb52e2 100644 --- a/launcher/icons/IconList.h +++ b/launcher/icons/IconList.h @@ -21,14 +21,15 @@ #include <QDir> #include <QtGui/QIcon> #include <memory> + #include "MMCIcon.h" #include "settings/Setting.h" -#include "Env.h" // there is a global icon list inside Env. -#include <icons/IIconList.h> + +#include "QObjectPtr.h" class QFileSystemWatcher; -class IconList : public QAbstractListModel, public IIconList +class IconList : public QAbstractListModel { Q_OBJECT public: @@ -42,19 +43,19 @@ public: virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; - bool addThemeIcon(const QString &key); - bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) override; - void saveIcon(const QString &key, const QString &path, const char * format) const override; - bool deleteIcon(const QString &key) override; - bool iconFileExists(const QString &key) const override; - virtual QStringList mimeTypes() const override; virtual Qt::DropActions supportedDropActions() const override; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; virtual Qt::ItemFlags flags(const QModelIndex &index) const override; - void installIcons(const QStringList &iconFiles) override; - void installIcon(const QString &file, const QString &name) override; + bool addThemeIcon(const QString &key); + bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type); + void saveIcon(const QString &key, const QString &path, const char * format) const; + bool deleteIcon(const QString &key); + bool iconFileExists(const QString &key) const; + + void installIcons(const QStringList &iconFiles); + void installIcon(const QString &file, const QString &name); const MMCIcon * icon(const QString &key) const; diff --git a/launcher/icons/MMCIcon.h b/launcher/icons/MMCIcon.h index 1f05f28e..13d99318 100644 --- a/launcher/icons/MMCIcon.h +++ b/launcher/icons/MMCIcon.h @@ -17,7 +17,15 @@ #include <QString> #include <QDateTime> #include <QIcon> -#include <icons/IIconList.h> + +enum IconType : unsigned +{ + Builtin, + Transient, + FileBased, + ICONS_TOTAL, + ToBeDeleted +}; struct MMCImage { diff --git a/launcher/java/JavaChecker.cpp b/launcher/java/JavaChecker.cpp index 81c61ab0..80c599cc 100644 --- a/launcher/java/JavaChecker.cpp +++ b/launcher/java/JavaChecker.cpp @@ -1,14 +1,14 @@ #include "JavaChecker.h" -#include "JavaUtils.h" -#include <FileSystem.h> -#include <Commandline.h> + #include <QFile> #include <QProcess> #include <QMap> -#include <QCoreApplication> #include <QDebug> -#include "Env.h" +#include "JavaUtils.h" +#include "FileSystem.h" +#include "Commandline.h" +#include "Application.h" JavaChecker::JavaChecker(QObject *parent) : QObject(parent) { @@ -16,7 +16,7 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent) void JavaChecker::performCheck() { - QString checkerJar = FS::PathCombine(ENV.getJarsPath(), "JavaCheck.jar"); + QString checkerJar = FS::PathCombine(APPLICATION->getJarsPath(), "JavaCheck.jar"); QStringList args; diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 0bded03c..07f2bd8c 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -29,13 +29,13 @@ JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent) { } -shared_qobject_ptr<Task> JavaInstallList::getLoadTask() +Task::Ptr JavaInstallList::getLoadTask() { load(); return getCurrentTask(); } -shared_qobject_ptr<Task> JavaInstallList::getCurrentTask() +Task::Ptr JavaInstallList::getCurrentTask() { if(m_status == Status::InProgress) { diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h index e5c72b17..3c237edf 100644 --- a/launcher/java/JavaInstallList.h +++ b/launcher/java/JavaInstallList.h @@ -40,7 +40,7 @@ class JavaInstallList : public BaseVersionList public: explicit JavaInstallList(QObject *parent = 0); - shared_qobject_ptr<Task> getLoadTask() override; + Task::Ptr getLoadTask() override; bool isLoaded() override; const BaseVersionPtr at(int i) const override; int count() const override; @@ -54,7 +54,7 @@ public slots: protected: void load(); - shared_qobject_ptr<Task> getCurrentTask(); + Task::Ptr getCurrentTask(); protected: Status m_status = Status::NotDone; diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index dff196ce..6b58db37 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -265,12 +265,18 @@ QList<QString> JavaUtils::FindJavaPaths() QList<JavaInstallPtr> ADOPTOPENJDK64s = this->FindJavaFromRegistryKey( KEY_WOW64_64KEY, "SOFTWARE\\AdoptOpenJDK\\JDK", "Path", "\\hotspot\\MSI"); - // Adoptium (Eclipse) - QList<JavaInstallPtr> ECLIPSEJDK32s = this->FindJavaFromRegistryKey( + // Foundation (Eclipse) + QList<JavaInstallPtr> FOUNDATIONJDK32s = this->FindJavaFromRegistryKey( KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); - QList<JavaInstallPtr> ECLIPSEJDK64s = this->FindJavaFromRegistryKey( + QList<JavaInstallPtr> FOUNDATIONJDK64s = this->FindJavaFromRegistryKey( KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Foundation\\JDK", "Path", "\\hotspot\\MSI"); + // Adoptium (Eclipse) + QList<JavaInstallPtr> ADOPTIUMJDK32s = this->FindJavaFromRegistryKey( + KEY_WOW64_32KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); + QList<JavaInstallPtr> ADOPTIUMJDK64s = this->FindJavaFromRegistryKey( + KEY_WOW64_64KEY, "SOFTWARE\\Eclipse Adoptium\\JDK", "Path", "\\hotspot\\MSI"); + // Microsoft QList<JavaInstallPtr> MICROSOFTJDK64s = this->FindJavaFromRegistryKey( KEY_WOW64_64KEY, "SOFTWARE\\Microsoft\\JDK", "Path", "\\hotspot\\MSI"); @@ -297,7 +303,8 @@ QList<QString> JavaUtils::FindJavaPaths() java_candidates.append(JDK64s); java_candidates.append(NEWJDK64s); java_candidates.append(ADOPTOPENJDK64s); - java_candidates.append(ECLIPSEJDK64s); + java_candidates.append(FOUNDATIONJDK64s); + java_candidates.append(ADOPTIUMJDK64s); java_candidates.append(MICROSOFTJDK64s); java_candidates.append(ZULU64s); java_candidates.append(LIBERICA64s); @@ -311,7 +318,8 @@ QList<QString> JavaUtils::FindJavaPaths() java_candidates.append(JDK32s); java_candidates.append(NEWJDK32s); java_candidates.append(ADOPTOPENJDK32s); - java_candidates.append(ECLIPSEJDK32s); + java_candidates.append(FOUNDATIONJDK32s); + java_candidates.append(ADOPTIUMJDK32s); java_candidates.append(ZULU32s); java_candidates.append(LIBERICA32s); diff --git a/launcher/java/launch/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp index fb338231..fb338231 100644 --- a/launcher/java/launch/CheckJava.cpp +++ b/launcher/launch/steps/CheckJava.cpp diff --git a/launcher/java/launch/CheckJava.h b/launcher/launch/steps/CheckJava.h index 68cd618b..68cd618b 100644 --- a/launcher/java/launch/CheckJava.h +++ b/launcher/launch/steps/CheckJava.h diff --git a/launcher/launch/steps/Update.h b/launcher/launch/steps/Update.h index 0c9d91e0..ce40611e 100644 --- a/launcher/launch/steps/Update.h +++ b/launcher/launch/steps/Update.h @@ -39,7 +39,7 @@ private slots: void updateFinished(); private: - shared_qobject_ptr<Task> m_updateTask; + Task::Ptr m_updateTask; bool m_aborted = false; Net::Mode m_mode = Net::Mode::Offline; }; diff --git a/launcher/main.cpp b/launcher/main.cpp index 3c2b9445..aabb5a06 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -1,8 +1,4 @@ -#include "Launcher.h" -#include "MainWindow.h" -#include "LaunchController.h" -#include <InstanceList.h> -#include <QDebug> +#include "Application.h" // #define BREAK_INFINITE_LOOP // #define BREAK_EXCEPTION @@ -34,12 +30,12 @@ int main(int argc, char *argv[]) #endif // initialize Qt - Launcher app(argc, argv); + Application app(argc, argv); switch (app.status()) { - case Launcher::StartingUp: - case Launcher::Initialized: + case Application::StartingUp: + case Application::Initialized: { Q_INIT_RESOURCE(multimc); Q_INIT_RESOURCE(backgrounds); @@ -55,9 +51,9 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(flat); return app.exec(); } - case Launcher::Failed: + case Application::Failed: return 1; - case Launcher::Succeeded: + case Application::Succeeded: return 0; } } diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp index 5ff7a59a..a9d62fcd 100644 --- a/launcher/meta/BaseEntity.cpp +++ b/launcher/meta/BaseEntity.cpp @@ -15,16 +15,13 @@ #include "BaseEntity.h" -#include "Json.h" - #include "net/Download.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" - -#include "Env.h" #include "Json.h" #include "BuildConfig.h" +#include "Application.h" class ParsingValidator : public Net::Validator { @@ -120,9 +117,9 @@ void Meta::BaseEntity::load(Net::Mode loadType) { return; } - NetJob *job = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename())); + m_updateTask = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename())); auto url = this->url(); - auto entry = ENV.metacache()->resolveEntry("meta", localFilename()); + auto entry = APPLICATION->metacache()->resolveEntry("meta", localFilename()); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); /* @@ -130,21 +127,20 @@ void Meta::BaseEntity::load(Net::Mode loadType) * If that fails, the file is not written to storage. */ dl->addValidator(new ParsingValidator(this)); - job->addNetAction(dl); + m_updateTask->addNetAction(dl); m_updateStatus = UpdateStatus::InProgress; - m_updateTask.reset(job); - QObject::connect(job, &NetJob::succeeded, [&]() + QObject::connect(m_updateTask.get(), &NetJob::succeeded, [&]() { m_loadStatus = LoadStatus::Remote; m_updateStatus = UpdateStatus::Succeeded; m_updateTask.reset(); }); - QObject::connect(job, &NetJob::failed, [&]() + QObject::connect(m_updateTask.get(), &NetJob::failed, [&]() { m_updateStatus = UpdateStatus::Failed; m_updateTask.reset(); }); - m_updateTask->start(); + m_updateTask->start(APPLICATION->network()); } bool Meta::BaseEntity::isLoaded() const @@ -158,7 +154,7 @@ bool Meta::BaseEntity::shouldStartRemoteUpdate() const return m_updateStatus != UpdateStatus::InProgress; } -shared_qobject_ptr<Task> Meta::BaseEntity::getCurrentTask() +Task::Ptr Meta::BaseEntity::getCurrentTask() { if(m_updateStatus == UpdateStatus::InProgress) { diff --git a/launcher/meta/BaseEntity.h b/launcher/meta/BaseEntity.h index eff43879..75fa384a 100644 --- a/launcher/meta/BaseEntity.h +++ b/launcher/meta/BaseEntity.h @@ -20,8 +20,8 @@ #include "QObjectPtr.h" #include "net/Mode.h" +#include "net/NetJob.h" -class Task; namespace Meta { class BaseEntity @@ -54,7 +54,7 @@ public: bool shouldStartRemoteUpdate() const; void load(Net::Mode loadType); - shared_qobject_ptr<Task> getCurrentTask(); + Task::Ptr getCurrentTask(); protected: /* methods */ bool loadLocalFile(); @@ -62,6 +62,6 @@ protected: /* methods */ private: LoadStatus m_loadStatus = LoadStatus::NotLoaded; UpdateStatus m_updateStatus = UpdateStatus::NotDone; - shared_qobject_ptr<Task> m_updateTask; + NetJob::Ptr m_updateTask; }; } diff --git a/launcher/meta/Index_test.cpp b/launcher/meta/Index_test.cpp index b0892070..5d3ddc50 100644 --- a/launcher/meta/Index_test.cpp +++ b/launcher/meta/Index_test.cpp @@ -3,19 +3,12 @@ #include "meta/Index.h" #include "meta/VersionList.h" -#include "Env.h" class IndexTest : public QObject { Q_OBJECT private slots: - void test_isProvidedByEnv() - { - QVERIFY(ENV.metadataIndex()); - QCOMPARE(ENV.metadataIndex(), ENV.metadataIndex()); - } - void test_hasUid_and_getList() { Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")}); diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp index 607007eb..6d23ce9a 100644 --- a/launcher/meta/VersionList.cpp +++ b/launcher/meta/VersionList.cpp @@ -29,7 +29,7 @@ VersionList::VersionList(const QString &uid, QObject *parent) setObjectName("Version list: " + uid); } -shared_qobject_ptr<Task> VersionList::getLoadTask() +Task::Ptr VersionList::getLoadTask() { load(Net::Mode::Online); return getCurrentTask(); diff --git a/launcher/meta/VersionList.h b/launcher/meta/VersionList.h index 58cdafe7..378255df 100644 --- a/launcher/meta/VersionList.h +++ b/launcher/meta/VersionList.h @@ -41,7 +41,7 @@ public: VersionPtrRole }; - shared_qobject_ptr<Task> getLoadTask() override; + Task::Ptr getLoadTask() override; bool isLoaded() override; const BaseVersionPtr at(int i) const override; int count() const override; diff --git a/launcher/minecraft/AssetsUtils.cpp b/launcher/minecraft/AssetsUtils.cpp index c01733b6..1c65a212 100644 --- a/launcher/minecraft/AssetsUtils.cpp +++ b/launcher/minecraft/AssetsUtils.cpp @@ -284,7 +284,7 @@ bool reconstructAssets(QString assetsId, QString resourcesFolder) } -NetActionPtr AssetObject::getDownloadAction() +NetAction::Ptr AssetObject::getDownloadAction() { QFileInfo objectFile(getLocalPath()); if ((!objectFile.isFile()) || (objectFile.size() != size)) @@ -316,7 +316,7 @@ QString AssetObject::getRelPath() return hash.left(2) + "/" + hash; } -NetJobPtr AssetsIndex::getDownloadJob() +NetJob::Ptr AssetsIndex::getDownloadJob() { auto job = new NetJob(QObject::tr("Assets for %1").arg(id)); for (auto &object : objects.values()) diff --git a/launcher/minecraft/AssetsUtils.h b/launcher/minecraft/AssetsUtils.h index 32e57060..3dbf19ed 100644 --- a/launcher/minecraft/AssetsUtils.h +++ b/launcher/minecraft/AssetsUtils.h @@ -25,7 +25,7 @@ struct AssetObject QString getRelPath(); QUrl getUrl(); QString getLocalPath(); - NetActionPtr getDownloadAction(); + NetAction::Ptr getDownloadAction(); QString hash; qint64 size; @@ -33,7 +33,7 @@ struct AssetObject struct AssetsIndex { - NetJobPtr getDownloadJob(); + NetJob::Ptr getDownloadJob(); QString id; QMap<QString, AssetObject> objects; diff --git a/launcher/minecraft/Component.cpp b/launcher/minecraft/Component.cpp index 92821065..c7dd5e36 100644 --- a/launcher/minecraft/Component.cpp +++ b/launcher/minecraft/Component.cpp @@ -1,14 +1,16 @@ #include <meta/VersionList.h> #include <meta/Index.h> -#include <Env.h> #include "Component.h" +#include <QSaveFile> + #include "meta/Version.h" #include "VersionFile.h" #include "minecraft/PackProfile.h" -#include <FileSystem.h> -#include <QSaveFile> +#include "FileSystem.h" #include "OneSixVersionFormat.h" +#include "Application.h" + #include <assert.h> Component::Component(PackProfile * parent, const QString& uid) @@ -85,9 +87,9 @@ std::shared_ptr<class VersionFile> Component::getVersionFile() const std::shared_ptr<class Meta::VersionList> Component::getVersionList() const { // FIXME: what if the metadata index isn't loaded yet? - if(ENV.metadataIndex()->hasUid(m_uid)) + if(APPLICATION->metadataIndex()->hasUid(m_uid)) { - return ENV.metadataIndex()->get(m_uid); + return APPLICATION->metadataIndex()->get(m_uid); } return nullptr; } @@ -192,7 +194,7 @@ bool Component::isRevertible() { if (isCustom()) { - if(ENV.metadataIndex()->hasUid(m_uid)) + if(APPLICATION->metadataIndex()->hasUid(m_uid)) { return true; } @@ -266,7 +268,7 @@ void Component::setVersion(const QString& version) // we don't have a file, therefore we are loaded with metadata m_cachedVersion = version; // see if the meta version is loaded - auto metaVersion = ENV.metadataIndex()->get(m_uid, version); + auto metaVersion = APPLICATION->metadataIndex()->get(m_uid, version); if(metaVersion->isLoaded()) { // if yes, we can continue with that. @@ -350,7 +352,7 @@ bool Component::revert() m_file.reset(); // check local cache for metadata... - auto version = ENV.metadataIndex()->get(m_uid, m_version); + auto version = APPLICATION->metadataIndex()->get(m_uid, m_version); if(version->isLoaded()) { m_metaVersion = version; diff --git a/launcher/minecraft/ComponentUpdateTask.cpp b/launcher/minecraft/ComponentUpdateTask.cpp index 241d9a49..8bc05a1b 100644 --- a/launcher/minecraft/ComponentUpdateTask.cpp +++ b/launcher/minecraft/ComponentUpdateTask.cpp @@ -3,16 +3,17 @@ #include "PackProfile_p.h" #include "PackProfile.h" #include "Component.h" -#include <Env.h> -#include <meta/Index.h> -#include <meta/VersionList.h> -#include <meta/Version.h> +#include "meta/Index.h" +#include "meta/VersionList.h" +#include "meta/Version.h" #include "ComponentUpdateTask_p.h" -#include <cassert> -#include <Version.h> +#include "cassert" +#include "Version.h" #include "net/Mode.h" #include "OneSixVersionFormat.h" +#include "Application.h" + /* * This is responsible for loading the components of a component list AND resolving dependency issues between them */ @@ -68,7 +69,7 @@ LoadResult composeLoadResult(LoadResult a, LoadResult b) return a; } -static LoadResult loadComponent(ComponentPtr component, shared_qobject_ptr<Task>& loadTask, Net::Mode netmode) +static LoadResult loadComponent(ComponentPtr component, Task::Ptr& loadTask, Net::Mode netmode) { if(component->m_loaded) { @@ -102,7 +103,7 @@ static LoadResult loadComponent(ComponentPtr component, shared_qobject_ptr<Task> } else { - auto metaVersion = ENV.metadataIndex()->get(component->m_uid, component->m_version); + auto metaVersion = APPLICATION->metadataIndex()->get(component->m_uid, component->m_version); component->m_metaVersion = metaVersion; if(metaVersion->isLoaded()) { @@ -126,7 +127,7 @@ static LoadResult loadComponent(ComponentPtr component, shared_qobject_ptr<Task> // FIXME: dead code. determine if this can still be useful? /* -static LoadResult loadPackProfile(ComponentPtr component, shared_qobject_ptr<Task>& loadTask, Net::Mode netmode) +static LoadResult loadPackProfile(ComponentPtr component, Task::Ptr& loadTask, Net::Mode netmode) { if(component->m_loaded) { @@ -135,7 +136,7 @@ static LoadResult loadPackProfile(ComponentPtr component, shared_qobject_ptr<Tas } LoadResult result = LoadResult::Failed; - auto metaList = ENV.metadataIndex()->get(component->m_uid); + auto metaList = APPLICATION->metadataIndex()->get(component->m_uid); if(metaList->isLoaded()) { component->m_loaded = true; @@ -151,16 +152,16 @@ static LoadResult loadPackProfile(ComponentPtr component, shared_qobject_ptr<Tas } */ -static LoadResult loadIndex(shared_qobject_ptr<Task>& loadTask, Net::Mode netmode) +static LoadResult loadIndex(Task::Ptr& loadTask, Net::Mode netmode) { // FIXME: DECIDE. do we want to run the update task anyway? - if(ENV.metadataIndex()->isLoaded()) + if(APPLICATION->metadataIndex()->isLoaded()) { qDebug() << "Index is already loaded"; return LoadResult::LoadedLocal; } - ENV.metadataIndex()->load(netmode); - loadTask = ENV.metadataIndex()->getCurrentTask(); + APPLICATION->metadataIndex()->load(netmode); + loadTask = APPLICATION->metadataIndex()->getCurrentTask(); if(loadTask) { return LoadResult::RequiresRemote; @@ -179,7 +180,7 @@ void ComponentUpdateTask::loadComponents() // load the main index (it is needed to determine if components can revert) { // FIXME: tear out as a method? or lambda? - shared_qobject_ptr<Task> indexLoadTask; + Task::Ptr indexLoadTask; auto singleResult = loadIndex(indexLoadTask, d->netmode); result = composeLoadResult(result, singleResult); if(indexLoadTask) @@ -202,7 +203,7 @@ void ComponentUpdateTask::loadComponents() // load all the components OR their lists... for (auto component: d->m_list->d->components) { - shared_qobject_ptr<Task> loadTask; + Task::Ptr loadTask; LoadResult singleResult; RemoteLoadStatus::Type loadType; // FIXME: to do this right, we need to load the lists and decide on which versions to use during dependency resolution. For now, ignore all that... diff --git a/launcher/minecraft/Library.cpp b/launcher/minecraft/Library.cpp index f2293679..c7982705 100644 --- a/launcher/minecraft/Library.cpp +++ b/launcher/minecraft/Library.cpp @@ -3,7 +3,6 @@ #include <net/Download.h> #include <net/ChecksumValidator.h> -#include <Env.h> #include <FileSystem.h> #include <BuildConfig.h> @@ -45,14 +44,14 @@ void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& na } } -QList< std::shared_ptr< NetAction > > Library::getDownloads( +QList<NetAction::Ptr> Library::getDownloads( OpSys system, class HttpMetaCache* cache, QStringList& failedLocalFiles, const QString & overridePath ) const { - QList<NetActionPtr> out; + QList<NetAction::Ptr> out; bool stale = isAlwaysStale(); bool local = isLocal(); diff --git a/launcher/minecraft/Library.h b/launcher/minecraft/Library.h index 119b4a86..41d41a8b 100644 --- a/launcher/minecraft/Library.h +++ b/launcher/minecraft/Library.h @@ -152,7 +152,7 @@ public: /* methods */ bool isForge() const; // Get a list of downloads for this library - QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache, + QList<NetAction::Ptr> getDownloads(OpSys system, class HttpMetaCache * cache, QStringList & failedLocalFiles, const QString & overridePath) const; private: /* methods */ diff --git a/launcher/minecraft/Library_test.cpp b/launcher/minecraft/Library_test.cpp index 75bb4db1..47531ad6 100644 --- a/launcher/minecraft/Library_test.cpp +++ b/launcher/minecraft/Library_test.cpp @@ -55,7 +55,7 @@ slots: auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString()); QCOMPARE(downloads.size(), 1); QCOMPARE(failedFiles, {}); - NetActionPtr dl = downloads[0]; + NetAction::Ptr dl = downloads[0]; QCOMPARE(dl->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion.jar")); } void test_legacy_url_local_broken() diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 2982a340..4c16e572 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -1,15 +1,16 @@ #include "MinecraftInstance.h" -#include <minecraft/launch/CreateGameFolders.h> -#include <minecraft/launch/ExtractNatives.h> -#include <minecraft/launch/PrintInstanceInfo.h> -#include <settings/Setting.h> +#include "minecraft/launch/CreateGameFolders.h" +#include "minecraft/launch/ExtractNatives.h" +#include "minecraft/launch/PrintInstanceInfo.h" +#include "settings/Setting.h" #include "settings/SettingsObject.h" -#include "Env.h" -#include <MMCStrings.h> -#include <pathmatcher/RegexpMatcher.h> -#include <pathmatcher/MultiMatcher.h> -#include <FileSystem.h> -#include <java/JavaVersion.h> +#include "Application.h" + +#include "MMCStrings.h" +#include "pathmatcher/RegexpMatcher.h" +#include "pathmatcher/MultiMatcher.h" +#include "FileSystem.h" +#include "java/JavaVersion.h" #include "MMCTime.h" #include "launch/LaunchTask.h" @@ -18,6 +19,8 @@ #include "launch/steps/Update.h" #include "launch/steps/PreLaunchCommand.h" #include "launch/steps/TextPrint.h" +#include "launch/steps/CheckJava.h" + #include "minecraft/launch/LauncherPartLaunch.h" #include "minecraft/launch/DirectJavaLaunch.h" #include "minecraft/launch/ModMinecraftJar.h" @@ -25,25 +28,26 @@ #include "minecraft/launch/ReconstructAssets.h" #include "minecraft/launch/ScanModFolders.h" #include "minecraft/launch/VerifyJavaInstall.h" -#include "java/launch/CheckJava.h" + #include "java/JavaUtils.h" + #include "meta/Index.h" #include "meta/VersionList.h" +#include "icons/IconList.h" + #include "mod/ModFolderModel.h" #include "mod/ResourcePackFolderModel.h" #include "mod/TexturePackFolderModel.h" -#include "WorldList.h" -#include "icons/IIconList.h" +#include "WorldList.h" -#include <QCoreApplication> #include "PackProfile.h" #include "AssetsUtils.h" #include "MinecraftUpdate.h" #include "MinecraftLoadAndCheck.h" -#include <minecraft/gameoptions/GameOptions.h> -#include <minecraft/update/FoldersTask.h> +#include "minecraft/gameoptions/GameOptions.h" +#include "minecraft/update/FoldersTask.h" #define IBUS "@im=ibus" @@ -794,17 +798,17 @@ QString MinecraftInstance::getStatusbarDescription() return description; } -shared_qobject_ptr<Task> MinecraftInstance::createUpdateTask(Net::Mode mode) +Task::Ptr MinecraftInstance::createUpdateTask(Net::Mode mode) { switch (mode) { case Net::Mode::Offline: { - return shared_qobject_ptr<Task>(new MinecraftLoadAndCheck(this)); + return Task::Ptr(new MinecraftLoadAndCheck(this)); } case Net::Mode::Online: { - return shared_qobject_ptr<Task>(new MinecraftUpdate(this)); + return Task::Ptr(new MinecraftUpdate(this)); } } return nullptr; @@ -816,7 +820,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this())); auto pptr = process.get(); - ENV.icons()->saveIcon(iconKey(), FS::PathCombine(gameRoot(), "icon.png"), "PNG"); + APPLICATION->icons()->saveIcon(iconKey(), FS::PathCombine(gameRoot(), "icon.png"), "PNG"); // print a header { diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index b11270e6..bb45f37b 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -77,7 +77,7 @@ public: std::shared_ptr<GameOptions> gameOptionsModel() const; ////// Launch stuff ////// - shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override; + Task::Ptr createUpdateTask(Net::Mode mode) override; shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override; QStringList extraArguments() const override; QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override; diff --git a/launcher/minecraft/MinecraftLoadAndCheck.h b/launcher/minecraft/MinecraftLoadAndCheck.h index 3435b52b..bfeae46b 100644 --- a/launcher/minecraft/MinecraftLoadAndCheck.h +++ b/launcher/minecraft/MinecraftLoadAndCheck.h @@ -41,7 +41,7 @@ private slots: private: MinecraftInstance *m_inst = nullptr; - shared_qobject_ptr<Task> m_task; + Task::Ptr m_task; QString m_preFailure; QString m_fail_reason; }; diff --git a/launcher/minecraft/MinecraftUpdate.cpp b/launcher/minecraft/MinecraftUpdate.cpp index 8f1565b0..32e9cbb6 100644 --- a/launcher/minecraft/MinecraftUpdate.cpp +++ b/launcher/minecraft/MinecraftUpdate.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "Env.h" #include "MinecraftUpdate.h" #include "MinecraftInstance.h" diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index f6918116..59a8f133 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -20,22 +20,23 @@ #include <QJsonDocument> #include <QJsonArray> #include <QDebug> - -#include "Exception.h" -#include <minecraft/OneSixVersionFormat.h> -#include <FileSystem.h> #include <QSaveFile> -#include <Env.h> -#include <meta/Index.h> -#include <minecraft/MinecraftInstance.h> #include <QUuid> #include <QTimer> -#include <Json.h> + +#include "Exception.h" +#include "minecraft/OneSixVersionFormat.h" +#include "FileSystem.h" +#include "meta/Index.h" +#include "minecraft/MinecraftInstance.h" +#include "Json.h" #include "PackProfile.h" #include "PackProfile_p.h" #include "ComponentUpdateTask.h" +#include "Application.h" + PackProfile::PackProfile(MinecraftInstance * instance) : QAbstractListModel() { @@ -339,7 +340,7 @@ void PackProfile::reload(Net::Mode netmode) } } -shared_qobject_ptr<Task> PackProfile::getCurrentTask() +Task::Ptr PackProfile::getCurrentTask() { return d->m_updateTask; } @@ -481,7 +482,7 @@ bool PackProfile::migratePreComponentConfig() } else if(!intendedVersion.isEmpty()) { - auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion); + auto metaVersion = APPLICATION->metadataIndex()->get(uid, intendedVersion); component = new Component(this, metaVersion); } else @@ -546,7 +547,7 @@ bool PackProfile::migratePreComponentConfig() auto patchVersion = d->getOldConfigVersion(uid); if(!patchVersion.isEmpty() && !loadedComponents.contains(uid)) { - auto patch = new Component(this, ENV.metadataIndex()->get(uid, patchVersion)); + auto patch = new Component(this, APPLICATION->metadataIndex()->get(uid, patchVersion)); patch->setOrder(order); loadedComponents[uid] = patch; } diff --git a/launcher/minecraft/PackProfile.h b/launcher/minecraft/PackProfile.h index 3d6cc6c3..f30deb5a 100644 --- a/launcher/minecraft/PackProfile.h +++ b/launcher/minecraft/PackProfile.h @@ -85,7 +85,7 @@ public: void resolve(Net::Mode netmode); /// get current running task... - shared_qobject_ptr<Task> getCurrentTask(); + Task::Ptr getCurrentTask(); std::shared_ptr<LaunchProfile> getProfile() const; diff --git a/launcher/minecraft/PackProfile_p.h b/launcher/minecraft/PackProfile_p.h index 6cd2a4e5..fce921bb 100644 --- a/launcher/minecraft/PackProfile_p.h +++ b/launcher/minecraft/PackProfile_p.h @@ -35,7 +35,7 @@ struct PackProfileData ComponentIndex componentIndex; bool dirty = false; QTimer m_saveTimer; - shared_qobject_ptr<Task> m_updateTask; + Task::Ptr m_updateTask; bool loaded = false; bool interactionDisabled = true; }; diff --git a/launcher/minecraft/VersionFilterData.cpp b/launcher/minecraft/VersionFilterData.cpp index 38e7b60c..c286d266 100644 --- a/launcher/minecraft/VersionFilterData.cpp +++ b/launcher/minecraft/VersionFilterData.cpp @@ -68,4 +68,5 @@ VersionFilterData::VersionFilterData() java8BeginsDate = timeFromS3Time("2017-03-30T09:32:19+00:00"); java16BeginsDate = timeFromS3Time("2021-05-12T11:19:15+00:00"); + java17BeginsDate = timeFromS3Time("2021-11-16T17:04:48+00:00"); } diff --git a/launcher/minecraft/VersionFilterData.h b/launcher/minecraft/VersionFilterData.h index 79756c3f..13445a51 100644 --- a/launcher/minecraft/VersionFilterData.h +++ b/launcher/minecraft/VersionFilterData.h @@ -25,5 +25,7 @@ struct VersionFilterData QDateTime java8BeginsDate; // release data of first version to require Java 16 (21w19a) QDateTime java16BeginsDate; + // release data of first version to require Java 17 (1.18 Pre Release 2) + QDateTime java17BeginsDate; }; extern VersionFilterData g_VersionFilterData; diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index 5c6de9df..8aa4e37f 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -207,6 +207,35 @@ MinecraftProfile profileFromJSONV3(const QJsonObject &parent, const char * token return out; } +void entitlementToJSONV3(QJsonObject &parent, MinecraftEntitlement p) { + if(p.validity == Katabasis::Validity::None) { + return; + } + QJsonObject out; + out["ownsMinecraft"] = QJsonValue(p.ownsMinecraft); + out["canPlayMinecraft"] = QJsonValue(p.canPlayMinecraft); + parent["entitlement"] = out; +} + +bool entitlementFromJSONV3(const QJsonObject &parent, MinecraftEntitlement & out) { + auto entitlementObject = parent.value("entitlement").toObject(); + if(entitlementObject.isEmpty()) { + return false; + } + { + auto ownsMinecraftV = entitlementObject.value("ownsMinecraft"); + auto canPlayMinecraftV = entitlementObject.value("canPlayMinecraft"); + if(!ownsMinecraftV.isBool() || !canPlayMinecraftV.isBool()) { + qWarning() << "mandatory attributes are missing or of unexpected type"; + return false; + } + out.canPlayMinecraft = canPlayMinecraftV.toBool(false); + out.ownsMinecraft = ownsMinecraftV.toBool(false); + out.validity = Katabasis::Validity::Assumed; + } + return true; +} + } bool AccountData::resumeStateFromV2(QJsonObject data) { @@ -304,9 +333,15 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { yggdrasilToken = tokenFromJSONV3(data, "ygg"); minecraftProfile = profileFromJSONV3(data, "profile"); + if(!entitlementFromJSONV3(data, minecraftEntitlement)) { + if(minecraftProfile.validity != Katabasis::Validity::None) { + minecraftEntitlement.canPlayMinecraft = true; + minecraftEntitlement.ownsMinecraft = true; + minecraftEntitlement.validity = Katabasis::Validity::Assumed; + } + } validity_ = minecraftProfile.validity; - return true; } @@ -331,6 +366,7 @@ QJsonObject AccountData::saveState() const { tokenToJSONV3(output, yggdrasilToken, "ygg"); profileToJSONV3(output, minecraftProfile, "profile"); + entitlementToJSONV3(output, minecraftEntitlement); return output; } @@ -378,7 +414,12 @@ QString AccountData::profileId() const { } QString AccountData::profileName() const { - return minecraftProfile.name; + if(minecraftProfile.name.size() == 0) { + return QObject::tr("No profile (%1)").arg(accountDisplayString()); + } + else { + return minecraftProfile.name; + } } QString AccountData::accountDisplayString() const { diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index cf58fb76..09cd2c73 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -21,6 +21,12 @@ struct Cape { QByteArray data; }; +struct MinecraftEntitlement { + bool ownsMinecraft = false; + bool canPlayMinecraft = false; + Katabasis::Validity validity = Katabasis::Validity::None; +}; + struct MinecraftProfile { QString id; QString name; @@ -69,5 +75,6 @@ struct AccountData { Katabasis::Token yggdrasilToken; MinecraftProfile minecraftProfile; + MinecraftEntitlement minecraftEntitlement; Katabasis::Validity validity_ = Katabasis::Validity::None; }; diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index a76cac55..d7537345 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -37,6 +37,8 @@ enum AccountListVersion { AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { } +AccountList::~AccountList() noexcept {} + int AccountList::findAccountByProfileId(const QString& profileId) const { for (int i = 0; i < count(); i++) { MinecraftAccountPtr account = at(i); @@ -62,28 +64,41 @@ const MinecraftAccountPtr AccountList::at(int i) const return MinecraftAccountPtr(m_accounts.at(i)); } +QStringList AccountList::profileNames() const { + QStringList out; + for(auto & account: m_accounts) { + auto profileName = account->profileName(); + if(profileName.isEmpty()) { + continue; + } + out.append(profileName); + } + return out; +} + void AccountList::addAccount(const MinecraftAccountPtr account) { - // We only ever want accounts with valid profiles. - // Keeping profile-less accounts is pointless and serves no purpose. auto profileId = account->profileId(); - if(!profileId.size()) { - return; - } - - // override/replace existing account with the same profileId - auto existingAccount = findAccountByProfileId(profileId); - if(existingAccount != -1) { - m_accounts[existingAccount] = account; - emit dataChanged(index(existingAccount), index(existingAccount, columnCount(QModelIndex()) - 1)); - onListChanged(); - return; + if(profileId.size()) { + // override/replace existing account with the same profileId + auto existingAccount = findAccountByProfileId(profileId); + if(existingAccount != -1) { + MinecraftAccountPtr existingAccountPtr = m_accounts[existingAccount]; + m_accounts[existingAccount] = account; + if(m_defaultAccount == existingAccountPtr) { + m_defaultAccount = account; + } + emit dataChanged(index(existingAccount), index(existingAccount, columnCount(QModelIndex()) - 1)); + onListChanged(); + return; + } } - // if we don't have this porfileId yet, add the account to the end + // if we don't have this profileId yet, add the account to the end int row = m_accounts.count(); beginInsertRows(QModelIndex(), row, row); - connect(account.get(), SIGNAL(changed()), SLOT(accountChanged())); + connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); endInsertRows(); onListChanged(); @@ -95,10 +110,10 @@ void AccountList::removeAccount(QModelIndex index) if(index.isValid() && row >= 0 && row < m_accounts.size()) { auto & account = m_accounts[row]; - if(account == m_activeAccount) + if(account == m_defaultAccount) { - m_activeAccount = nullptr; - onActiveChanged(); + m_defaultAccount = nullptr; + onDefaultAccountChanged(); } beginRemoveRows(QModelIndex(), row, row); m_accounts.removeAt(index.row()); @@ -107,54 +122,54 @@ void AccountList::removeAccount(QModelIndex index) } } -MinecraftAccountPtr AccountList::activeAccount() const +MinecraftAccountPtr AccountList::defaultAccount() const { - return m_activeAccount; + return m_defaultAccount; } -void AccountList::setActiveAccount(const QString &profileId) +void AccountList::setDefaultAccount(MinecraftAccountPtr newAccount) { - if (profileId.isEmpty() && m_activeAccount) + if (!newAccount && m_defaultAccount) { int idx = 0; - auto prevActiveAcc = m_activeAccount; - m_activeAccount = nullptr; + auto previousDefaultAccount = m_defaultAccount; + m_defaultAccount = nullptr; for (MinecraftAccountPtr account : m_accounts) { - if (account == prevActiveAcc) + if (account == previousDefaultAccount) { - emit dataChanged(index(idx), index(idx)); + emit dataChanged(index(idx), index(idx, columnCount(QModelIndex()) - 1)); } idx ++; } - onActiveChanged(); + onDefaultAccountChanged(); } else { - auto currentActiveAccount = m_activeAccount; - int currentActiveAccountIdx = -1; - auto newActiveAccount = m_activeAccount; - int newActiveAccountIdx = -1; + auto currentDefaultAccount = m_defaultAccount; + int currentDefaultAccountIdx = -1; + auto newDefaultAccount = m_defaultAccount; + int newDefaultAccountIdx = -1; int idx = 0; for (MinecraftAccountPtr account : m_accounts) { - if (account->profileId() == profileId) + if (account == newAccount) { - newActiveAccount = account; - newActiveAccountIdx = idx; + newDefaultAccount = account; + newDefaultAccountIdx = idx; } - if(currentActiveAccount == account) + if(currentDefaultAccount == account) { - currentActiveAccountIdx = idx; + currentDefaultAccountIdx = idx; } idx++; } - if(currentActiveAccount != newActiveAccount) + if(currentDefaultAccount != newDefaultAccount) { - emit dataChanged(index(currentActiveAccountIdx), index(currentActiveAccountIdx)); - emit dataChanged(index(newActiveAccountIdx), index(newActiveAccountIdx)); - m_activeAccount = newActiveAccount; - onActiveChanged(); + emit dataChanged(index(currentDefaultAccountIdx), index(currentDefaultAccountIdx, columnCount(QModelIndex()) - 1)); + emit dataChanged(index(newDefaultAccountIdx), index(newDefaultAccountIdx, columnCount(QModelIndex()) - 1)); + m_defaultAccount = newDefaultAccount; + onDefaultAccountChanged(); } } } @@ -165,6 +180,23 @@ void AccountList::accountChanged() onListChanged(); } +void AccountList::accountActivityChanged(bool active) +{ + MinecraftAccount *account = qobject_cast<MinecraftAccount *>(sender()); + bool found = false; + for (int i = 0; i < count(); i++) { + if (at(i).get() == account) { + emit dataChanged(index(i), index(i, columnCount(QModelIndex()) - 1)); + found = true; + break; + } + } + if(found) { + emit listActivityChanged(); + } +} + + void AccountList::onListChanged() { if (m_autosave) @@ -174,12 +206,12 @@ void AccountList::onListChanged() emit listChanged(); } -void AccountList::onActiveChanged() +void AccountList::onDefaultAccountChanged() { if (m_autosave) saveList(); - emit activeAccountChanged(); + emit defaultAccountChanged(); } int AccountList::count() const @@ -211,6 +243,16 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return typeStr; } + case StatusColumn: { + if(account->isActive()) { + return tr("Working", "Account status"); + } + if(account->isExpired()) { + return tr("Expired", "Account status"); + } + return tr("Ready", "Account status"); + } + case ProfileNameColumn: { return account->profileName(); } @@ -235,13 +277,13 @@ QVariant AccountList::data(const QModelIndex &index, int role) const return account->accountDisplayString(); case PointerRole: - return qVariantFromValue(account); + return QVariant::fromValue(account); case Qt::CheckStateRole: switch (index.column()) { case NameColumn: - return account == m_activeAccount ? Qt::Checked : Qt::Unchecked; + return account == m_defaultAccount ? Qt::Checked : Qt::Unchecked; } default: @@ -260,6 +302,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r return tr("Account"); case TypeColumn: return tr("Type"); + case StatusColumn: + return tr("Status"); case MigrationColumn: return tr("Can Migrate?"); case ProfileNameColumn: @@ -275,6 +319,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r return tr("User name of the account."); case TypeColumn: return tr("Type of the account - Mojang or MSA."); + case StatusColumn: + return tr("Current status of the account."); case MigrationColumn: return tr("Can this account migrate to Microsoft account?"); case ProfileNameColumn: @@ -309,9 +355,9 @@ Qt::ItemFlags AccountList::flags(const QModelIndex &index) const return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -bool AccountList::setData(const QModelIndex &index, const QVariant &value, int role) +bool AccountList::setData(const QModelIndex &idx, const QVariant &value, int role) { - if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid()) + if (idx.row() < 0 || idx.row() >= rowCount(idx) || !idx.isValid()) { return false; } @@ -320,12 +366,12 @@ bool AccountList::setData(const QModelIndex &index, const QVariant &value, int r { if(value == Qt::Checked) { - MinecraftAccountPtr account = at(index.row()); - setActiveAccount(account->profileId()); + MinecraftAccountPtr account = at(idx.row()); + setDefaultAccount(account); } } - emit dataChanged(index, index); + emit dataChanged(idx, index(idx.row(), columnCount(QModelIndex()) - 1)); return true; } @@ -395,7 +441,7 @@ bool AccountList::loadList() bool AccountList::loadV2(QJsonObject& root) { beginResetModel(); - auto activeUserName = root.value("activeAccount").toString(""); + auto defaultUserName = root.value("activeAccount").toString(""); QJsonArray accounts = root.value("accounts").toArray(); for (QJsonValue accountVal : accounts) { @@ -411,9 +457,10 @@ bool AccountList::loadV2(QJsonObject& root) { continue; } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); - if (activeUserName.size() && account->mojangUserName() == activeUserName) { - m_activeAccount = account; + if (defaultUserName.size() && account->mojangUserName() == defaultUserName) { + m_defaultAccount = account; } } else @@ -435,16 +482,16 @@ bool AccountList::loadV3(QJsonObject& root) { if (account.get() != nullptr) { auto profileId = account->profileId(); - if(!profileId.size()) { - continue; - } - if(findAccountByProfileId(profileId) != -1) { - continue; + if(profileId.size()) { + if(findAccountByProfileId(profileId) != -1) { + continue; + } } connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged); + connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged); m_accounts.append(account); if(accountObj.value("active").toBool(false)) { - m_activeAccount = account; + m_defaultAccount = account; } } else @@ -491,7 +538,7 @@ bool AccountList::saveList() for (MinecraftAccountPtr account : m_accounts) { QJsonObject accountObj = account->saveToJson(); - if(m_activeAccount == account) { + if(m_defaultAccount == account) { accountObj["active"] = true; } accounts.append(accountObj); diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index e275eb17..08004628 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -42,11 +42,13 @@ public: ProfileNameColumn, MigrationColumn, TypeColumn, + StatusColumn, NUM_COLUMNS }; explicit AccountList(QObject *parent = 0); + virtual ~AccountList() noexcept; const MinecraftAccountPtr at(int i) const; int count() const; @@ -63,6 +65,7 @@ public: void removeAccount(QModelIndex index); int findAccountByProfileId(const QString &profileId) const; MinecraftAccountPtr getAccountByProfileName(const QString &profileName) const; + QStringList profileNames() const; /*! * Sets the path to load/save the list file from/to. @@ -78,13 +81,14 @@ public: bool loadV3(QJsonObject &root); bool saveList(); - MinecraftAccountPtr activeAccount() const; - void setActiveAccount(const QString &profileId); + MinecraftAccountPtr defaultAccount() const; + void setDefaultAccount(MinecraftAccountPtr profileId); bool anyAccountIsValid(); signals: void listChanged(); - void activeAccountChanged(); + void listActivityChanged(); + void defaultAccountChanged(); public slots: /** @@ -92,6 +96,11 @@ public slots: */ void accountChanged(); + /** + * This is called when a (refresh/login) task involving the account starts or ends + */ + void accountActivityChanged(bool active); + protected: /*! * Called whenever the list changes. @@ -101,13 +110,13 @@ protected: /*! * Called whenever the active account changes. - * Emits the activeAccountChanged() signal and autosaves the list if enabled. + * Emits the defaultAccountChanged() signal and autosaves the list if enabled. */ - void onActiveChanged(); + void onDefaultAccountChanged(); QList<MinecraftAccountPtr> m_accounts; - MinecraftAccountPtr m_activeAccount; + MinecraftAccountPtr m_defaultAccount; //! Path to the account list file. Empty string if there isn't one. QString m_listFilePath; diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp index d400ce8d..25d753de 100644 --- a/launcher/minecraft/auth/AccountTask.cpp +++ b/launcher/minecraft/auth/AccountTask.cpp @@ -23,10 +23,6 @@ #include <QNetworkReply> #include <QByteArray> -#include <Env.h> - -#include <BuildConfig.h> - #include <QDebug> AccountTask::AccountTask(AccountData *data, QObject *parent) diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h index f609d5d3..55fbdf39 100644 --- a/launcher/minecraft/auth/AuthSession.h +++ b/launcher/minecraft/auth/AuthSession.h @@ -3,8 +3,10 @@ #include <QString> #include <QMultiMap> #include <memory> +#include "QObjectPtr.h" class MinecraftAccount; +class QNetworkAccessManager; struct AuthSession { @@ -17,6 +19,7 @@ struct AuthSession Undetermined, RequiresOAuth, RequiresPassword, + RequiresProfileSetup, PlayableOffline, PlayableOnline, GoneOrMigrated @@ -40,7 +43,6 @@ struct AuthSession bool auth_server_online = false; // Did the user request online mode? bool wants_online = true; - std::shared_ptr<MinecraftAccount> m_accountPtr; }; typedef std::shared_ptr<AuthSession> AuthSessionPtr; diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index 2d76f9ac..30ed6afe 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -28,11 +28,16 @@ #include <QDebug> #include <QPainter> -#include <minecraft/auth/flows/MSASilent.h> -#include <minecraft/auth/flows/MSAInteractive.h> +#include "flows/MSASilent.h" +#include "flows/MSAInteractive.h" + +#include "flows/MojangRefresh.h" +#include "flows/MojangLogin.h" + +MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) { + m_internalId = QUuid::createUuid().toString().remove(QRegExp("[{}-]")); +} -#include <minecraft/auth/flows/MojangRefresh.h> -#include <minecraft/auth/flows/MojangLogin.h> MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json) { MinecraftAccountPtr account(new MinecraftAccount()); @@ -52,7 +57,7 @@ MinecraftAccountPtr MinecraftAccount::loadFromJsonV3(const QJsonObject& json) { MinecraftAccountPtr MinecraftAccount::createFromUsername(const QString &username) { - MinecraftAccountPtr account(new MinecraftAccount()); + MinecraftAccountPtr account = new MinecraftAccount(); account->data.type = AccountType::Mojang; account->data.yggdrasilToken.extra["userName"] = username; account->data.yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegExp("[{}-]")); @@ -91,6 +96,23 @@ AccountStatus MinecraftAccount::accountStatus() const { } } +bool MinecraftAccount::isExpired() const { + switch(data.type) { + case AccountType::Mojang: { + return data.accessToken().isEmpty(); + } + break; + case AccountType::MSA: { + return data.msaToken.validity == Katabasis::Validity::None; + } + break; + default: { + return true; + } + } +} + + QPixmap MinecraftAccount::getFace() const { QPixmap skinTexture; if(!skinTexture.loadFromData(data.minecraftProfile.skin.data, "PNG")) { @@ -104,7 +126,7 @@ QPixmap MinecraftAccount::getFace() const { } -std::shared_ptr<AccountTask> MinecraftAccount::login(AuthSessionPtr session, QString password) +shared_qobject_ptr<AccountTask> MinecraftAccount::login(AuthSessionPtr session, QString password) { Q_ASSERT(m_currentTask.get() == nullptr); @@ -140,11 +162,12 @@ std::shared_ptr<AccountTask> MinecraftAccount::login(AuthSessionPtr session, QSt connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } -std::shared_ptr<AccountTask> MinecraftAccount::loginMSA(AuthSessionPtr session) { +shared_qobject_ptr<AccountTask> MinecraftAccount::loginMSA(AuthSessionPtr session) { Q_ASSERT(m_currentTask.get() == nullptr); if(accountStatus() == Verified && !session->wants_online) @@ -161,11 +184,12 @@ std::shared_ptr<AccountTask> MinecraftAccount::loginMSA(AuthSessionPtr session) connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } -std::shared_ptr<AccountTask> MinecraftAccount::refresh(AuthSessionPtr session) { +shared_qobject_ptr<AccountTask> MinecraftAccount::refresh(AuthSessionPtr session) { Q_ASSERT(m_currentTask.get() == nullptr); // take care of the true offline status @@ -203,6 +227,7 @@ std::shared_ptr<AccountTask> MinecraftAccount::refresh(AuthSessionPtr session) { connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + emit activityChanged(true); } return m_currentTask; } @@ -213,13 +238,27 @@ void MinecraftAccount::authSucceeded() auto session = m_currentTask->getAssignedSession(); if (session) { - session->status = - session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline; + /* + session->status = AuthSession::RequiresProfileSetup; + session->auth_server_online = true; + */ + if(data.profileId().size() == 0) { + session->status = AuthSession::RequiresProfileSetup; + } + else { + if(session->wants_online) { + session->status = AuthSession::PlayableOnline; + } + else { + session->status = AuthSession::PlayableOffline; + } + } fillSession(session); session->auth_server_online = true; } m_currentTask.reset(); emit changed(); + emit activityChanged(false); } void MinecraftAccount::authFailed(QString reason) @@ -284,6 +323,45 @@ void MinecraftAccount::authFailed(QString reason) } } m_currentTask.reset(); + emit activityChanged(false); +} + +bool MinecraftAccount::isActive() const { + return m_currentTask; +} + +bool MinecraftAccount::shouldRefresh() const { + /* + * Never refresh accounts that are being used by the game, it breaks the game session. + * Always refresh accounts that have not been refreshed yet during this session. + * Don't refresh broken accounts. + * Refresh accounts that would expire in the next 12 hours (fresh token validity is 24 hours). + */ + if(isInUse()) { + return false; + } + switch(data.validity_) { + case Katabasis::Validity::Certain: { + break; + } + case Katabasis::Validity::None: { + return false; + } + case Katabasis::Validity::Assumed: { + return true; + } + } + auto now = QDateTime::currentDateTimeUtc(); + auto issuedTimestamp = data.yggdrasilToken.issueInstant; + auto expiresTimestamp = data.yggdrasilToken.notAfter; + + if(!expiresTimestamp.isValid()) { + expiresTimestamp = issuedTimestamp.addSecs(24 * 3600); + } + if (now.secsTo(expiresTimestamp) < 12 * 3600) { + return true; + } + return false; } void MinecraftAccount::fillSession(AuthSessionPtr session) @@ -309,7 +387,6 @@ void MinecraftAccount::fillSession(AuthSessionPtr session) { session->session = "-"; } - session->m_accountPtr = shared_from_this(); } void MinecraftAccount::decrementUses() diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 5b0c1ec7..459ef903 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -27,12 +27,13 @@ #include "AuthSession.h" #include "Usable.h" #include "AccountData.h" +#include "QObjectPtr.h" class Task; class AccountTask; class MinecraftAccount; -typedef std::shared_ptr<MinecraftAccount> MinecraftAccountPtr; +typedef shared_qobject_ptr<MinecraftAccount> MinecraftAccountPtr; Q_DECLARE_METATYPE(MinecraftAccountPtr) /** @@ -63,8 +64,7 @@ enum AccountStatus */ class MinecraftAccount : public QObject, - public Usable, - public std::enable_shared_from_this<MinecraftAccount> + public Usable { Q_OBJECT public: /* construction */ @@ -72,7 +72,7 @@ public: /* construction */ explicit MinecraftAccount(const MinecraftAccount &other, QObject *parent) = delete; //! Default constructor - explicit MinecraftAccount(QObject *parent = 0) : QObject(parent) {}; + explicit MinecraftAccount(QObject *parent = 0); static MinecraftAccountPtr createFromUsername(const QString &username); @@ -90,13 +90,17 @@ public: /* manipulation */ * 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<AccountTask> login(AuthSessionPtr session, QString password = QString()); + shared_qobject_ptr<AccountTask> login(AuthSessionPtr session, QString password); - std::shared_ptr<AccountTask> loginMSA(AuthSessionPtr session); + shared_qobject_ptr<AccountTask> loginMSA(AuthSessionPtr session); - std::shared_ptr<AccountTask> refresh(AuthSessionPtr session); + shared_qobject_ptr<AccountTask> refresh(AuthSessionPtr session); public: /* queries */ + QString internalId() const { + return m_internalId; + } + QString accountDisplayString() const { return data.accountDisplayString(); } @@ -117,6 +121,10 @@ public: /* queries */ return data.profileName(); } + bool isActive() const; + + bool isExpired() const; + bool canMigrate() const { return data.canMigrateToMSA; } @@ -153,19 +161,24 @@ public: /* queries */ return &data; } + bool shouldRefresh() const; + signals: /** * This signal is emitted when the account changes */ void changed(); + void activityChanged(bool active); + // TODO: better signalling for the various possible state changes - especially errors protected: /* variables */ + QString m_internalId; AccountData data; // current task we are executing here - std::shared_ptr<AccountTask> m_currentTask; + shared_qobject_ptr<AccountTask> m_currentTask; protected: /* methods */ diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp index 9fb3ec48..00957fd4 100644 --- a/launcher/minecraft/auth/flows/AuthContext.cpp +++ b/launcher/minecraft/auth/flows/AuthContext.cpp @@ -4,25 +4,21 @@ #include <QDesktopServices> #include <QMetaEnum> #include <QDebug> - #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> - +#include <QUuid> #include <QUrlQuery> -#include <QPixmap> -#include <QPainter> - #include "AuthContext.h" #include "katabasis/Globals.h" #include "AuthRequest.h" -#include "Secrets.h" +#include "Parsers.h" -#include "Env.h" +#include <Application.h> -using OAuth2 = Katabasis::OAuth2; +using OAuth2 = Katabasis::DeviceFlow; using Activity = Katabasis::Activity; AuthContext::AuthContext(AccountData * data, QObject *parent) : @@ -54,25 +50,17 @@ void AuthContext::initMSA() { return; } - auto clientId = Secrets::getMSAClientID('-'); - if(clientId.isEmpty()) { - return; - } - - Katabasis::OAuth2::Options opts; + OAuth2::Options opts; opts.scope = "XboxLive.signin offline_access"; - opts.clientIdentifier = clientId; + opts.clientIdentifier = APPLICATION->msaClientId(); opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"; opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"; - opts.listenerPorts = {28562, 28563, 28564, 28565, 28566}; - m_oauth2 = new OAuth2(opts, m_data->msaToken, this, &ENV.qnam()); - m_oauth2->setGrantFlow(Katabasis::OAuth2::GrantFlowDevice); + // FIXME: OAuth2 is not aware of our fancy shared pointers + m_oauth2 = new OAuth2(opts, m_data->msaToken, this, APPLICATION->network().get()); - connect(m_oauth2, &OAuth2::linkingFailed, this, &AuthContext::onOAuthLinkingFailed); - connect(m_oauth2, &OAuth2::linkingSucceeded, this, &AuthContext::onOAuthLinkingSucceeded); - connect(m_oauth2, &OAuth2::showVerificationUriAndCode, this, &AuthContext::showVerificationUriAndCode); connect(m_oauth2, &OAuth2::activityChanged, this, &AuthContext::onOAuthActivityChanged); + connect(m_oauth2, &OAuth2::showVerificationUriAndCode, this, &AuthContext::showVerificationUriAndCode); } void AuthContext::initMojang() { @@ -97,50 +85,56 @@ void AuthContext::onMojangFailed() { changeState(m_yggdrasil->accountState(), tr("Mojang user authentication failed.")); } -/* -bool AuthContext::signOut() { - if(isBusy()) { - return false; - } - - start(); - - beginActivity(Activity::LoggingOut); - m_oauth2->unlink(); - m_account = AccountData(); - finishActivity(); - return true; -} -*/ - -void AuthContext::onOAuthLinkingFailed() { - emit hideVerificationUriAndCode(); - finishActivity(); - changeState(STATE_FAILED_HARD, tr("Microsoft user authentication failed.")); -} - -void AuthContext::onOAuthLinkingSucceeded() { - emit hideVerificationUriAndCode(); - auto *o2t = qobject_cast<OAuth2 *>(sender()); - if (!o2t->linked()) { - finishActivity(); - changeState(STATE_FAILED_HARD, tr("Microsoft user authentication ended with an impossible state (succeeded, but not succeeded at the same time).")); - return; - } - QVariantMap extraTokens = o2t->extraTokens(); -#ifndef NDEBUG - if (!extraTokens.isEmpty()) { - qDebug() << "Extra tokens in response:"; - foreach (QString key, extraTokens.keys()) { - qDebug() << "\t" << key << ":" << extraTokens.value(key); +void AuthContext::onOAuthActivityChanged(Katabasis::Activity activity) { + switch(activity) { + case Katabasis::Activity::Idle: + case Katabasis::Activity::LoggingIn: + case Katabasis::Activity::Refreshing: + case Katabasis::Activity::LoggingOut: { + // We asked it to do something, it's doing it. Nothing to act upon. + return; } - } + case Katabasis::Activity::Succeeded: { + // Succeeded or did not invalidate tokens + emit hideVerificationUriAndCode(); + if (!m_oauth2->linked()) { + finishActivity(); + changeState(STATE_FAILED_HARD, tr("Microsoft user authentication ended with an impossible state (succeeded, but not succeeded at the same time).")); + return; + } + QVariantMap extraTokens = m_oauth2->extraTokens(); +#ifndef NDEBUG + if (!extraTokens.isEmpty()) { + qDebug() << "Extra tokens in response:"; + foreach (QString key, extraTokens.keys()) { + qDebug() << "\t" << key << ":" << extraTokens.value(key); + } + } #endif - doUserAuth(); -} + doUserAuth(); + return; + } + case Katabasis::Activity::FailedSoft: { + emit hideVerificationUriAndCode(); + finishActivity(); + changeState(STATE_FAILED_SOFT, tr("Microsoft user authentication failed with a soft error.")); + return; + } + case Katabasis::Activity::FailedGone: + case Katabasis::Activity::FailedHard: { + emit hideVerificationUriAndCode(); + finishActivity(); + changeState(STATE_FAILED_HARD, tr("Microsoft user authentication failed.")); + return; + } + default: { + emit hideVerificationUriAndCode(); + finishActivity(); + changeState(STATE_FAILED_HARD, tr("Microsoft user authentication completed with an unrecognized result.")); + return; + } -void AuthContext::onOAuthActivityChanged(Katabasis::Activity activity) { - // respond to activity change here + } } void AuthContext::doUserAuth() { @@ -169,137 +163,6 @@ void AuthContext::doUserAuth() { qDebug() << "First layer of XBox auth ... commencing."; } -namespace { -bool getDateTime(QJsonValue value, QDateTime & out) { - if(!value.isString()) { - return false; - } - out = QDateTime::fromString(value.toString(), Qt::ISODate); - return out.isValid(); -} - -bool getString(QJsonValue value, QString & out) { - if(!value.isString()) { - return false; - } - out = value.toString(); - return true; -} - -bool getNumber(QJsonValue value, double & out) { - if(!value.isDouble()) { - return false; - } - out = value.toDouble(); - return true; -} - -bool getNumber(QJsonValue value, int64_t & out) { - if(!value.isDouble()) { - return false; - } - out = (int64_t) value.toDouble(); - return true; -} - -bool getBool(QJsonValue value, bool & out) { - if(!value.isBool()) { - return false; - } - out = value.toBool(); - return true; -} - -/* -{ - "IssueInstant":"2020-12-07T19:52:08.4463796Z", - "NotAfter":"2020-12-21T19:52:08.4463796Z", - "Token":"token", - "DisplayClaims":{ - "xui":[ - { - "uhs":"userhash" - } - ] - } - } -*/ -// TODO: handle error responses ... -/* -{ - "Identity":"0", - "XErr":2148916238, - "Message":"", - "Redirect":"https://start.ui.xboxlive.com/AddChildToFamily" -} -// 2148916233 = missing XBox account -// 2148916238 = child account not linked to a family -*/ - -bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, const char * name) { - qDebug() << "Parsing" << name <<":"; -#ifndef NDEBUG - qDebug() << data; -#endif - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); - return false; - } - - auto obj = doc.object(); - if(!getDateTime(obj.value("IssueInstant"), output.issueInstant)) { - qWarning() << "User IssueInstant is not a timestamp"; - return false; - } - if(!getDateTime(obj.value("NotAfter"), output.notAfter)) { - qWarning() << "User NotAfter is not a timestamp"; - return false; - } - if(!getString(obj.value("Token"), output.token)) { - qWarning() << "User Token is not a timestamp"; - return false; - } - auto arrayVal = obj.value("DisplayClaims").toObject().value("xui"); - if(!arrayVal.isArray()) { - qWarning() << "Missing xui claims array"; - return false; - } - bool foundUHS = false; - for(auto item: arrayVal.toArray()) { - if(!item.isObject()) { - continue; - } - auto obj = item.toObject(); - if(obj.contains("uhs")) { - foundUHS = true; - } else { - continue; - } - // consume all 'display claims' ... whatever that means - for(auto iter = obj.begin(); iter != obj.end(); iter++) { - QString claim; - if(!getString(obj.value(iter.key()), claim)) { - qWarning() << "display claim " << iter.key() << " is not a string..."; - return false; - } - output.extra[iter.key()] = claim; - } - - break; - } - if(!foundUHS) { - qWarning() << "Missing uhs"; - return false; - } - output.validity = Katabasis::Validity::Certain; - qDebug() << name << "is valid."; - return true; -} - -} - void AuthContext::onUserAuthDone( QNetworkReply::NetworkError error, QByteArray replyData, @@ -313,7 +176,7 @@ void AuthContext::onUserAuthDone( } Katabasis::Token temp; - if(!parseXTokenResponse(replyData, temp, "UToken")) { + if(!Parsers::parseXTokenResponse(replyData, temp, "UToken")) { qWarning() << "Could not parse user authentication response..."; finishActivity(); changeState(STATE_FAILED_HARD, tr("XBox user authentication response could not be understood.")); @@ -365,7 +228,7 @@ void AuthContext::doSTSAuthMinecraft() { void AuthContext::processSTSError(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers) { if(error == QNetworkReply::AuthenticationRequiredError) { - QJsonParseError jsonError; + QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error) { qWarning() << "Cannot parse error XSTS response as JSON: " << jsonError.errorString(); @@ -374,7 +237,7 @@ void AuthContext::processSTSError(QNetworkReply::NetworkError error, QByteArray int64_t errorCode = -1; auto obj = doc.object(); - if(!getNumber(obj.value("XErr"), errorCode)) { + if(!Parsers::getNumber(obj.value("XErr"), errorCode)) { qWarning() << "XErr is not a number"; return; } @@ -400,7 +263,7 @@ void AuthContext::onSTSAuthMinecraftDone( } Katabasis::Token temp; - if(!parseXTokenResponse(replyData, temp, "STSAuthMinecraft")) { + if(!Parsers::parseXTokenResponse(replyData, temp, "STSAuthMinecraft")) { qWarning() << "Could not parse authorization response for access to mojang services..."; failResult(m_mcAuthSucceeded); return; @@ -417,67 +280,33 @@ void AuthContext::onSTSAuthMinecraftDone( } void AuthContext::doMinecraftAuth() { + auto requestURL = "https://api.minecraftservices.com/launcher/login"; + auto uhs = m_data->mojangservicesToken.extra["uhs"].toString(); + auto xToken = m_data->mojangservicesToken.token; + QString mc_auth_template = R"XXX( { - "identityToken": "XBL3.0 x=%1;%2" + "xtoken": "XBL3.0 x=%1;%2", + "platform": "PC_LAUNCHER" } )XXX"; - auto data = mc_auth_template.arg(m_data->mojangservicesToken.extra["uhs"].toString(), m_data->mojangservicesToken.token); + auto requestBody = mc_auth_template.arg(uhs, xToken); - QNetworkRequest request = QNetworkRequest(QUrl("https://api.minecraftservices.com/authentication/login_with_xbox")); + QNetworkRequest request = QNetworkRequest(QUrl(requestURL)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Accept", "application/json"); AuthRequest *requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftAuthDone); - requestor->post(request, data.toUtf8()); + requestor->post(request, requestBody.toUtf8()); qDebug() << "Getting Minecraft access token..."; } -namespace { -bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { - QJsonParseError jsonError; - qDebug() << "Parsing Mojang response..."; -#ifndef NDEBUG - qDebug() << data; -#endif - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from api.minecraftservices.com/authentication/login_with_xbox as JSON: " << jsonError.errorString(); - return false; - } - - auto obj = doc.object(); - double expires_in = 0; - if(!getNumber(obj.value("expires_in"), expires_in)) { - qWarning() << "expires_in is not a valid number"; - return false; - } - auto currentTime = QDateTime::currentDateTimeUtc(); - output.issueInstant = currentTime; - output.notAfter = currentTime.addSecs(expires_in); - - QString username; - if(!getString(obj.value("username"), username)) { - qWarning() << "username is not valid"; - return false; - } - - // TODO: it's a JWT... validate it? - if(!getString(obj.value("access_token"), output.token)) { - qWarning() << "access_token is not valid"; - return false; - } - output.validity = Katabasis::Validity::Certain; - qDebug() << "Mojang response is valid."; - return true; -} -} - void AuthContext::onMinecraftAuthDone( QNetworkReply::NetworkError error, QByteArray replyData, QList<QNetworkReply::RawHeaderPair> headers ) { + qDebug() << replyData; if (error != QNetworkReply::NoError) { qWarning() << "Reply error:" << error; #ifndef NDEBUG @@ -487,7 +316,7 @@ void AuthContext::onMinecraftAuthDone( return; } - if(!parseMojangResponse(replyData, m_data->yggdrasilToken)) { + if(!Parsers::parseMojangResponse(replyData, m_data->yggdrasilToken)) { qWarning() << "Could not parse login_with_xbox response..."; #ifndef NDEBUG qDebug() << replyData; @@ -539,7 +368,7 @@ void AuthContext::onSTSAuthGenericDone( } Katabasis::Token temp; - if(!parseXTokenResponse(replyData, temp, "STSAuthGeneric")) { + if(!Parsers::parseXTokenResponse(replyData, temp, "STSAuthGeneric")) { qWarning() << "Could not parse authorization response for access to xbox API..."; failResult(m_xboxProfileSucceeded); return; @@ -619,7 +448,7 @@ void AuthContext::checkResult() { return; } if(m_mcAuthSucceeded && m_xboxProfileSucceeded) { - doMinecraftProfile(); + doEntitlements(); } else { finishActivity(); @@ -662,84 +491,33 @@ void AuthContext::checkResult() { } } -namespace { -bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { - qDebug() << "Parsing Minecraft profile..."; +void AuthContext::doEntitlements() { + auto uuid = QUuid::createUuid(); + entitlementsRequestId = uuid.toString().remove('{').remove('}'); + auto url = "https://api.minecraftservices.com/entitlements/license?requestId=" + entitlementsRequestId; + QNetworkRequest request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onEntitlementsDone); + requestor->get(request); + qDebug() << "Getting Xbox profile..."; +} + + +void AuthContext::onEntitlementsDone( + QNetworkReply::NetworkError error, + QByteArray data, + QList<QNetworkReply::RawHeaderPair> headers +) { #ifndef NDEBUG qDebug() << data; #endif - - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); - return false; - } - - auto obj = doc.object(); - if(!getString(obj.value("id"), output.id)) { - qWarning() << "Minecraft profile id is not a string"; - return false; - } - - if(!getString(obj.value("name"), output.name)) { - qWarning() << "Minecraft profile name is not a string"; - return false; - } - - auto skinsArray = obj.value("skins").toArray(); - for(auto skin: skinsArray) { - auto skinObj = skin.toObject(); - Skin skinOut; - if(!getString(skinObj.value("id"), skinOut.id)) { - continue; - } - QString state; - if(!getString(skinObj.value("state"), state)) { - continue; - } - if(state != "ACTIVE") { - continue; - } - if(!getString(skinObj.value("url"), skinOut.url)) { - continue; - } - if(!getString(skinObj.value("variant"), skinOut.variant)) { - continue; - } - // we deal with only the active skin - output.skin = skinOut; - break; - } - auto capesArray = obj.value("capes").toArray(); - - QString currentCape; - for(auto cape: capesArray) { - auto capeObj = cape.toObject(); - Cape capeOut; - if(!getString(capeObj.value("id"), capeOut.id)) { - continue; - } - QString state; - if(!getString(capeObj.value("state"), state)) { - continue; - } - if(state == "ACTIVE") { - currentCape = capeOut.id; - } - if(!getString(capeObj.value("url"), capeOut.url)) { - continue; - } - if(!getString(capeObj.value("alias"), capeOut.alias)) { - continue; - } - - output.capes[capeOut.id] = capeOut; - } - output.currentCape = currentCape; - output.validity = Katabasis::Validity::Certain; - return true; -} + // TODO: check presence of same entitlementsRequestId? + // TODO: validate JWTs? + Parsers::parseMinecraftEntitlements(data, m_data->minecraftEntitlement); + doMinecraftProfile(); } void AuthContext::doMinecraftProfile() { @@ -766,9 +544,13 @@ void AuthContext::onMinecraftProfileDone( qDebug() << data; #endif if (error == QNetworkReply::ContentNotFoundError) { + // NOTE: Succeed even if we do not have a profile. This is a valid account state. + if(m_data->type == AccountType::Mojang) { + m_data->minecraftEntitlement.canPlayMinecraft = false; + m_data->minecraftEntitlement.ownsMinecraft = false; + } m_data->minecraftProfile = MinecraftProfile(); - finishActivity(); - changeState(STATE_FAILED_HARD, tr("Account is missing a Minecraft Java profile.\n\nWhile the Microsoft account is valid, it does not own the game.\n\nYou might own Bedrock on this account, but that does not give you access to Java currently.")); + succeed(); return; } if (error != QNetworkReply::NoError) { @@ -776,7 +558,7 @@ void AuthContext::onMinecraftProfileDone( changeState(STATE_FAILED_HARD, tr("Minecraft Java profile acquisition failed.")); return; } - if(!parseMinecraftProfile(data, m_data->minecraftProfile)) { + if(!Parsers::parseMinecraftProfile(data, m_data->minecraftProfile)) { m_data->minecraftProfile = MinecraftProfile(); finishActivity(); changeState(STATE_FAILED_HARD, tr("Minecraft Java profile response could not be parsed")); @@ -784,6 +566,9 @@ void AuthContext::onMinecraftProfileDone( } if(m_data->type == AccountType::Mojang) { + auto validProfile = m_data->minecraftProfile.validity == Katabasis::Validity::Certain; + m_data->minecraftEntitlement.canPlayMinecraft = validProfile; + m_data->minecraftEntitlement.ownsMinecraft = validProfile; doMigrationEligibilityCheck(); } else { @@ -805,43 +590,13 @@ void AuthContext::doMigrationEligibilityCheck() { requestor->get(request); } -bool parseRolloutResponse(QByteArray & data, bool& result) { - qDebug() << "Parsing Rollout response..."; -#ifndef NDEBUG - qDebug() << data; -#endif - - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from https://api.minecraftservices.com/rollout/v1/msamigration as JSON: " << jsonError.errorString(); - return false; - } - - auto obj = doc.object(); - QString feature; - if(!getString(obj.value("feature"), feature)) { - qWarning() << "Rollout feature is not a string"; - return false; - } - if(feature != "msamigration") { - qWarning() << "Rollout feature is not what we expected (msamigration), but is instead \"" << feature << "\""; - return false; - } - if(!getBool(obj.value("rollout"), result)) { - qWarning() << "Rollout feature is not a string"; - return false; - } - return true; -} - void AuthContext::onMigrationEligibilityCheckDone( QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers ) { if (error == QNetworkReply::NoError) { - parseRolloutResponse(data, m_data->canMigrateToMSA); + Parsers::parseRolloutResponse(data, m_data->canMigrateToMSA); } doGetSkin(); } @@ -865,6 +620,11 @@ void AuthContext::onSkinDone( if (error == QNetworkReply::NoError) { m_data->minecraftProfile.skin.data = data; } + succeed(); + +} + +void AuthContext::succeed() { m_data->validity_ = Katabasis::Validity::Certain; finishActivity(); changeState(STATE_SUCCEEDED, tr("Finished all authentication steps")); diff --git a/launcher/minecraft/auth/flows/AuthContext.h b/launcher/minecraft/auth/flows/AuthContext.h index dc7552ac..5e4e9edc 100644 --- a/launcher/minecraft/auth/flows/AuthContext.h +++ b/launcher/minecraft/auth/flows/AuthContext.h @@ -7,7 +7,7 @@ #include <QNetworkReply> #include <QImage> -#include <katabasis/OAuth2.h> +#include <katabasis/DeviceFlow.h> #include "Yggdrasil.h" #include "../AccountData.h" #include "../AccountTask.h" @@ -35,9 +35,6 @@ signals: private slots: // OAuth-specific callbacks - void onOAuthLinkingSucceeded(); - void onOAuthLinkingFailed(); - void onOAuthActivityChanged(Katabasis::Activity activity); // Yggdrasil specific callbacks @@ -63,6 +60,9 @@ protected: void doXBoxProfile(); Q_SLOT void onXBoxProfileDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>); + void doEntitlements(); + Q_SLOT void onEntitlementsDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>); + void doMinecraftProfile(); Q_SLOT void onMinecraftProfileDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>); @@ -72,6 +72,8 @@ protected: void doGetSkin(); Q_SLOT void onSkinDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>); + void succeed(); + void failResult(bool & flag); void succeedResult(bool & flag); void checkResult(); @@ -82,12 +84,13 @@ protected: void clearTokens(); protected: - Katabasis::OAuth2 *m_oauth2 = nullptr; + Katabasis::DeviceFlow *m_oauth2 = nullptr; Yggdrasil *m_yggdrasil = nullptr; int m_requestsDone = 0; bool m_xboxProfileSucceeded = false; bool m_mcAuthSucceeded = false; + QString entitlementsRequestId; QSet<int64_t> stsErrors; bool stsFailed = false; diff --git a/launcher/minecraft/auth/flows/AuthRequest.cpp b/launcher/minecraft/auth/flows/AuthRequest.cpp index 77558fd3..82dba591 100644 --- a/launcher/minecraft/auth/flows/AuthRequest.cpp +++ b/launcher/minecraft/auth/flows/AuthRequest.cpp @@ -5,9 +5,9 @@ #include <QBuffer> #include <QUrlQuery> +#include "Application.h" #include "AuthRequest.h" #include "katabasis/Globals.h" -#include "Env.h" AuthRequest::AuthRequest(QObject *parent): QObject(parent) { } @@ -17,7 +17,7 @@ AuthRequest::~AuthRequest() { void AuthRequest::get(const QNetworkRequest &req, int timeout/* = 60*1000*/) { setup(req, QNetworkAccessManager::GetOperation); - reply_ = ENV.qnam().get(request_); + reply_ = APPLICATION->network()->get(request_); status_ = Requesting; timedReplies_.add(new Katabasis::Reply(reply_, timeout)); connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); @@ -29,7 +29,7 @@ void AuthRequest::post(const QNetworkRequest &req, const QByteArray &data, int t setup(req, QNetworkAccessManager::PostOperation); data_ = data; status_ = Requesting; - reply_ = ENV.qnam().post(request_, data_); + reply_ = APPLICATION->network()->post(request_, data_); timedReplies_.add(new Katabasis::Reply(reply_, timeout)); connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRequestError(QNetworkReply::NetworkError))); connect(reply_, SIGNAL(finished()), this, SLOT(onRequestFinished())); diff --git a/launcher/minecraft/auth/flows/AuthRequest.h b/launcher/minecraft/auth/flows/AuthRequest.h index 6a45a0bd..a547aea4 100644 --- a/launcher/minecraft/auth/flows/AuthRequest.h +++ b/launcher/minecraft/auth/flows/AuthRequest.h @@ -5,7 +5,6 @@ #include <QNetworkAccessManager> #include <QUrl> #include <QByteArray> -#include <QHttpMultiPart> #include "katabasis/Reply.h" diff --git a/launcher/minecraft/auth/flows/MSAInteractive.cpp b/launcher/minecraft/auth/flows/MSAInteractive.cpp index 03beb279..525aaf88 100644 --- a/launcher/minecraft/auth/flows/MSAInteractive.cpp +++ b/launcher/minecraft/auth/flows/MSAInteractive.cpp @@ -1,6 +1,9 @@ #include "MSAInteractive.h" -MSAInteractive::MSAInteractive(AccountData* data, QObject* parent) : AuthContext(data, parent) {} +MSAInteractive::MSAInteractive( + AccountData* data, + QObject* parent +) : AuthContext(data, parent) {} void MSAInteractive::executeTask() { m_requestsDone = 0; @@ -14,7 +17,6 @@ void MSAInteractive::executeTask() { m_oauth2->setExtraRequestParams(extraOpts); beginActivity(Katabasis::Activity::LoggingIn); - m_oauth2->unlink(); *m_data = AccountData(); - m_oauth2->link(); + m_oauth2->login(); } diff --git a/launcher/minecraft/auth/flows/MSAInteractive.h b/launcher/minecraft/auth/flows/MSAInteractive.h index 9556f254..6654e0d6 100644 --- a/launcher/minecraft/auth/flows/MSAInteractive.h +++ b/launcher/minecraft/auth/flows/MSAInteractive.h @@ -5,6 +5,9 @@ class MSAInteractive : public AuthContext { Q_OBJECT public: - explicit MSAInteractive(AccountData * data, QObject *parent = 0); + explicit MSAInteractive( + AccountData *data, + QObject *parent = 0 + ); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/MSASilent.h b/launcher/minecraft/auth/flows/MSASilent.h index e1b3d43d..a442b49e 100644 --- a/launcher/minecraft/auth/flows/MSASilent.h +++ b/launcher/minecraft/auth/flows/MSASilent.h @@ -5,6 +5,9 @@ class MSASilent : public AuthContext { Q_OBJECT public: - explicit MSASilent(AccountData * data, QObject *parent = 0); + explicit MSASilent( + AccountData * data, + QObject *parent = 0 + ); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/MojangLogin.cpp b/launcher/minecraft/auth/flows/MojangLogin.cpp index cca911b5..6c217cd1 100644 --- a/launcher/minecraft/auth/flows/MojangLogin.cpp +++ b/launcher/minecraft/auth/flows/MojangLogin.cpp @@ -1,6 +1,10 @@ #include "MojangLogin.h" -MojangLogin::MojangLogin(AccountData* data, QString password, QObject* parent) : AuthContext(data, parent), m_password(password) {} +MojangLogin::MojangLogin( + AccountData *data, + QString password, + QObject *parent +): AuthContext(data, parent), m_password(password) {} void MojangLogin::executeTask() { m_requestsDone = 0; diff --git a/launcher/minecraft/auth/flows/MojangLogin.h b/launcher/minecraft/auth/flows/MojangLogin.h index 2e765ae8..5f33752f 100644 --- a/launcher/minecraft/auth/flows/MojangLogin.h +++ b/launcher/minecraft/auth/flows/MojangLogin.h @@ -5,7 +5,11 @@ class MojangLogin : public AuthContext { Q_OBJECT public: - explicit MojangLogin(AccountData * data, QString password, QObject *parent = 0); + explicit MojangLogin( + AccountData *data, + QString password, + QObject *parent = 0 + ); void executeTask() override; private: diff --git a/launcher/minecraft/auth/flows/MojangRefresh.cpp b/launcher/minecraft/auth/flows/MojangRefresh.cpp index af99175c..008c0453 100644 --- a/launcher/minecraft/auth/flows/MojangRefresh.cpp +++ b/launcher/minecraft/auth/flows/MojangRefresh.cpp @@ -1,6 +1,9 @@ #include "MojangRefresh.h" -MojangRefresh::MojangRefresh(AccountData* data, QObject* parent) : AuthContext(data, parent) {} +MojangRefresh::MojangRefresh( + AccountData *data, + QObject *parent +) : AuthContext(data, parent) {} void MojangRefresh::executeTask() { m_requestsDone = 0; diff --git a/launcher/minecraft/auth/flows/MojangRefresh.h b/launcher/minecraft/auth/flows/MojangRefresh.h index fb4facd5..06e4e4ce 100644 --- a/launcher/minecraft/auth/flows/MojangRefresh.h +++ b/launcher/minecraft/auth/flows/MojangRefresh.h @@ -5,6 +5,6 @@ class MojangRefresh : public AuthContext { Q_OBJECT public: - explicit MojangRefresh(AccountData * data, QObject *parent = 0); + explicit MojangRefresh(AccountData *data, QObject *parent = 0); void executeTask() override; }; diff --git a/launcher/minecraft/auth/flows/Parsers.cpp b/launcher/minecraft/auth/flows/Parsers.cpp new file mode 100644 index 00000000..ecb11cf9 --- /dev/null +++ b/launcher/minecraft/auth/flows/Parsers.cpp @@ -0,0 +1,316 @@ +#include "Parsers.h" + +#include <QJsonDocument> +#include <QJsonArray> +#include <QDebug> + +namespace Parsers { + +bool getDateTime(QJsonValue value, QDateTime & out) { + if(!value.isString()) { + return false; + } + out = QDateTime::fromString(value.toString(), Qt::ISODate); + return out.isValid(); +} + +bool getString(QJsonValue value, QString & out) { + if(!value.isString()) { + return false; + } + out = value.toString(); + return true; +} + +bool getNumber(QJsonValue value, double & out) { + if(!value.isDouble()) { + return false; + } + out = value.toDouble(); + return true; +} + +bool getNumber(QJsonValue value, int64_t & out) { + if(!value.isDouble()) { + return false; + } + out = (int64_t) value.toDouble(); + return true; +} + +bool getBool(QJsonValue value, bool & out) { + if(!value.isBool()) { + return false; + } + out = value.toBool(); + return true; +} + +/* +{ + "IssueInstant":"2020-12-07T19:52:08.4463796Z", + "NotAfter":"2020-12-21T19:52:08.4463796Z", + "Token":"token", + "DisplayClaims":{ + "xui":[ + { + "uhs":"userhash" + } + ] + } + } +*/ +// TODO: handle error responses ... +/* +{ + "Identity":"0", + "XErr":2148916238, + "Message":"", + "Redirect":"https://start.ui.xboxlive.com/AddChildToFamily" +} +// 2148916233 = missing XBox account +// 2148916238 = child account not linked to a family +*/ + +bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, const char * name) { + qDebug() << "Parsing" << name <<":"; +#ifndef NDEBUG + qDebug() << data; +#endif + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + if(!getDateTime(obj.value("IssueInstant"), output.issueInstant)) { + qWarning() << "User IssueInstant is not a timestamp"; + return false; + } + if(!getDateTime(obj.value("NotAfter"), output.notAfter)) { + qWarning() << "User NotAfter is not a timestamp"; + return false; + } + if(!getString(obj.value("Token"), output.token)) { + qWarning() << "User Token is not a timestamp"; + return false; + } + auto arrayVal = obj.value("DisplayClaims").toObject().value("xui"); + if(!arrayVal.isArray()) { + qWarning() << "Missing xui claims array"; + return false; + } + bool foundUHS = false; + for(auto item: arrayVal.toArray()) { + if(!item.isObject()) { + continue; + } + auto obj = item.toObject(); + if(obj.contains("uhs")) { + foundUHS = true; + } else { + continue; + } + // consume all 'display claims' ... whatever that means + for(auto iter = obj.begin(); iter != obj.end(); iter++) { + QString claim; + if(!getString(obj.value(iter.key()), claim)) { + qWarning() << "display claim " << iter.key() << " is not a string..."; + return false; + } + output.extra[iter.key()] = claim; + } + + break; + } + if(!foundUHS) { + qWarning() << "Missing uhs"; + return false; + } + output.validity = Katabasis::Validity::Certain; + qDebug() << name << "is valid."; + return true; +} + +bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { + qDebug() << "Parsing Minecraft profile..."; +#ifndef NDEBUG + qDebug() << data; +#endif + + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + if(!getString(obj.value("id"), output.id)) { + qWarning() << "Minecraft profile id is not a string"; + return false; + } + + if(!getString(obj.value("name"), output.name)) { + qWarning() << "Minecraft profile name is not a string"; + return false; + } + + auto skinsArray = obj.value("skins").toArray(); + for(auto skin: skinsArray) { + auto skinObj = skin.toObject(); + Skin skinOut; + if(!getString(skinObj.value("id"), skinOut.id)) { + continue; + } + QString state; + if(!getString(skinObj.value("state"), state)) { + continue; + } + if(state != "ACTIVE") { + continue; + } + if(!getString(skinObj.value("url"), skinOut.url)) { + continue; + } + if(!getString(skinObj.value("variant"), skinOut.variant)) { + continue; + } + // we deal with only the active skin + output.skin = skinOut; + break; + } + auto capesArray = obj.value("capes").toArray(); + + QString currentCape; + for(auto cape: capesArray) { + auto capeObj = cape.toObject(); + Cape capeOut; + if(!getString(capeObj.value("id"), capeOut.id)) { + continue; + } + QString state; + if(!getString(capeObj.value("state"), state)) { + continue; + } + if(state == "ACTIVE") { + currentCape = capeOut.id; + } + if(!getString(capeObj.value("url"), capeOut.url)) { + continue; + } + if(!getString(capeObj.value("alias"), capeOut.alias)) { + continue; + } + + output.capes[capeOut.id] = capeOut; + } + output.currentCape = currentCape; + output.validity = Katabasis::Validity::Certain; + return true; +} + +bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) { + qDebug() << "Parsing Minecraft entitlements..."; +#ifndef NDEBUG + qDebug() << data; +#endif + + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + + auto itemsArray = obj.value("items").toArray(); + for(auto item: itemsArray) { + auto itemObj = item.toObject(); + QString name; + if(!getString(itemObj.value("name"), name)) { + continue; + } + if(name == "game_minecraft") { + output.canPlayMinecraft = true; + } + if(name == "product_minecraft") { + output.ownsMinecraft = true; + } + } + output.validity = Katabasis::Validity::Certain; + return true; +} + +bool parseRolloutResponse(QByteArray & data, bool& result) { + qDebug() << "Parsing Rollout response..."; +#ifndef NDEBUG + qDebug() << data; +#endif + + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from https://api.minecraftservices.com/rollout/v1/msamigration as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + QString feature; + if(!getString(obj.value("feature"), feature)) { + qWarning() << "Rollout feature is not a string"; + return false; + } + if(feature != "msamigration") { + qWarning() << "Rollout feature is not what we expected (msamigration), but is instead \"" << feature << "\""; + return false; + } + if(!getBool(obj.value("rollout"), result)) { + qWarning() << "Rollout feature is not a string"; + return false; + } + return true; +} + +bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) { + QJsonParseError jsonError; + qDebug() << "Parsing Mojang response..."; +#ifndef NDEBUG + qDebug() << data; +#endif + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from api.minecraftservices.com/launcher/login as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + double expires_in = 0; + if(!getNumber(obj.value("expires_in"), expires_in)) { + qWarning() << "expires_in is not a valid number"; + return false; + } + auto currentTime = QDateTime::currentDateTimeUtc(); + output.issueInstant = currentTime; + output.notAfter = currentTime.addSecs(expires_in); + + QString username; + if(!getString(obj.value("username"), username)) { + qWarning() << "username is not valid"; + return false; + } + + // TODO: it's a JWT... validate it? + if(!getString(obj.value("access_token"), output.token)) { + qWarning() << "access_token is not valid"; + return false; + } + output.validity = Katabasis::Validity::Certain; + qDebug() << "Mojang response is valid."; + return true; +} + +} diff --git a/launcher/minecraft/auth/flows/Parsers.h b/launcher/minecraft/auth/flows/Parsers.h new file mode 100644 index 00000000..b484a073 --- /dev/null +++ b/launcher/minecraft/auth/flows/Parsers.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../AccountData.h" + +namespace Parsers +{ + bool getDateTime(QJsonValue value, QDateTime & out); + bool getString(QJsonValue value, QString & out); + bool getNumber(QJsonValue value, double & out); + bool getNumber(QJsonValue value, int64_t & out); + bool getBool(QJsonValue value, bool & out); + + bool parseXTokenResponse(QByteArray &data, Katabasis::Token &output, const char * name); + bool parseMojangResponse(QByteArray &data, Katabasis::Token &output); + + bool parseMinecraftProfile(QByteArray &data, MinecraftProfile &output); + bool parseMinecraftEntitlements(QByteArray &data, MinecraftEntitlement &output); + bool parseRolloutResponse(QByteArray &data, bool& result); +} diff --git a/launcher/minecraft/auth/flows/Yggdrasil.cpp b/launcher/minecraft/auth/flows/Yggdrasil.cpp index 20ca63d0..5ea168e8 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.cpp +++ b/launcher/minecraft/auth/flows/Yggdrasil.cpp @@ -23,12 +23,10 @@ #include <QNetworkReply> #include <QByteArray> -#include <Env.h> - -#include <BuildConfig.h> - #include <QDebug> +#include "Application.h" + Yggdrasil::Yggdrasil(AccountData *data, QObject *parent) : AccountTask(data, parent) { @@ -40,7 +38,7 @@ void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) { QNetworkRequest netRequest(endpoint); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - m_netReply = ENV.qnam().post(netRequest, content); + m_netReply = APPLICATION->network()->post(netRequest, content); connect(m_netReply, &QNetworkReply::finished, this, &Yggdrasil::processReply); connect(m_netReply, &QNetworkReply::uploadProgress, this, &Yggdrasil::refreshTimers); connect(m_netReply, &QNetworkReply::downloadProgress, this, &Yggdrasil::refreshTimers); @@ -86,7 +84,7 @@ void Yggdrasil::refresh() { req.insert("requestUser", false); QJsonDocument doc(req); - QUrl reqUrl(BuildConfig.AUTH_BASE + "refresh"); + QUrl reqUrl("https://authserver.mojang.com/refresh"); QByteArray requestData = doc.toJson(); sendRequest(reqUrl, requestData); @@ -131,7 +129,7 @@ void Yggdrasil::login(QString password) { QJsonDocument doc(req); - QUrl reqUrl(BuildConfig.AUTH_BASE + "authenticate"); + QUrl reqUrl("https://authserver.mojang.com/authenticate"); QNetworkRequest netRequest(reqUrl); QByteArray requestData = doc.toJson(); @@ -140,20 +138,18 @@ void Yggdrasil::login(QString password) { -void Yggdrasil::refreshTimers(qint64, qint64) -{ +void Yggdrasil::refreshTimers(qint64, qint64) { timeout_keeper.stop(); timeout_keeper.start(timeout_max); progress(count = 0, timeout_max); } -void Yggdrasil::heartbeat() -{ + +void Yggdrasil::heartbeat() { count += time_step; progress(count, timeout_max); } -bool Yggdrasil::abort() -{ +bool Yggdrasil::abort() { progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_USER; @@ -161,19 +157,16 @@ bool Yggdrasil::abort() return true; } -void Yggdrasil::abortByTimeout() -{ +void Yggdrasil::abortByTimeout() { progress(timeout_max, timeout_max); // TODO: actually use this in a meaningful way m_aborted = Yggdrasil::BY_TIMEOUT; m_netReply->abort(); } -void Yggdrasil::sslErrors(QList<QSslError> errors) -{ +void Yggdrasil::sslErrors(QList<QSslError> errors) { int i = 1; - for (auto error : errors) - { + for (auto error : errors) { qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString(); auto cert = error.certificate(); qCritical() << "Certificate in question:\n" << cert.toText(); @@ -181,8 +174,7 @@ void Yggdrasil::sslErrors(QList<QSslError> errors) } } -void Yggdrasil::processResponse(QJsonObject responseData) -{ +void Yggdrasil::processResponse(QJsonObject responseData) { // Read the response data. We need to get the client token, access token, and the selected // profile. qDebug() << "Processing authentication response."; @@ -191,8 +183,7 @@ void Yggdrasil::processResponse(QJsonObject 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()) - { + 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; @@ -208,8 +199,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) // Now, we set the access token. qDebug() << "Getting access token."; QString accessToken = responseData.value("accessToken").toString(""); - if (accessToken.isEmpty()) - { + 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; @@ -217,6 +207,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) // Set the access token. m_data->yggdrasilToken.token = accessToken; m_data->yggdrasilToken.validity = Katabasis::Validity::Certain; + m_data->yggdrasilToken.issueInstant = QDateTime::currentDateTimeUtc(); // We've made it through the minefield of possible errors. Return true to indicate that // we've succeeded. @@ -224,8 +215,7 @@ void Yggdrasil::processResponse(QJsonObject responseData) changeState(STATE_SUCCEEDED); } -void Yggdrasil::processReply() -{ +void Yggdrasil::processReply() { changeState(STATE_WORKING); switch (m_netReply->error()) @@ -247,9 +237,9 @@ void Yggdrasil::processReply() "<li>You use Windows and need to update your root certificates, please install any outstanding updates.</li>" "<li>Some device on your network is interfering with SSL traffic. In that case, " "you have bigger worries than Minecraft not starting.</li>" - "<li>Possibly something else. Check the %1 log file for details</li>" + "<li>Possibly something else. Check the log file for details</li>" "</ul>" - ).arg(BuildConfig.LAUNCHER_NAME) + ) ); return; // used for invalid credentials and similar errors. Fall through. @@ -278,19 +268,16 @@ void Yggdrasil::processReply() // Check the response code. int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (responseCode == 200) - { + 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) - { + if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) { processResponse(replyData.size() > 0 ? doc.object() : QJsonObject()); return; } - else - { + else { changeState( STATE_FAILED_SOFT, tr("Failed to parse authentication server response JSON response: %1 at offset %2.").arg(jsonError.errorString()).arg(jsonError.offset) @@ -304,16 +291,14 @@ void Yggdrasil::processReply() // 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) - { + 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 - { + 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."; @@ -324,14 +309,12 @@ void Yggdrasil::processReply() } } -void Yggdrasil::processError(QJsonObject responseData) -{ +void Yggdrasil::processError(QJsonObject responseData) { QJsonValue errorVal = responseData.value("error"); QJsonValue errorMessageValue = responseData.value("errorMessage"); QJsonValue causeVal = responseData.value("cause"); - if (errorVal.isString() && errorMessageValue.isString()) - { + if (errorVal.isString() && errorMessageValue.isString()) { m_error = std::shared_ptr<Error>( new Error { errorVal.toString(""), @@ -341,8 +324,7 @@ void Yggdrasil::processError(QJsonObject responseData) ); changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose); } - else - { + 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.")); } diff --git a/launcher/minecraft/auth/flows/Yggdrasil.h b/launcher/minecraft/auth/flows/Yggdrasil.h index e709cb9f..b9670ec7 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.h +++ b/launcher/minecraft/auth/flows/Yggdrasil.h @@ -24,6 +24,7 @@ #include "../MinecraftAccount.h" +class QNetworkAccessManager; class QNetworkReply; /** @@ -33,7 +34,10 @@ class Yggdrasil : public AccountTask { Q_OBJECT public: - explicit Yggdrasil(AccountData * data, QObject *parent = 0); + explicit Yggdrasil( + AccountData *data, + QObject *parent = 0 + ); virtual ~Yggdrasil() {}; void refresh(); diff --git a/launcher/minecraft/launch/ClaimAccount.cpp b/launcher/minecraft/launch/ClaimAccount.cpp index a1180f0a..bb4f6806 100644 --- a/launcher/minecraft/launch/ClaimAccount.cpp +++ b/launcher/minecraft/launch/ClaimAccount.cpp @@ -1,11 +1,15 @@ #include "ClaimAccount.h" #include <launch/LaunchTask.h> +#include "Application.h" +#include "minecraft/auth/AccountList.h" + ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchStep(parent) { if(session->status == AuthSession::Status::PlayableOnline) { - m_account = session->m_accountPtr; + auto accounts = APPLICATION->accounts(); + m_account = accounts->getAccountByProfileName(session->player_name); } } diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp index ff022c40..8fd11eca 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.cpp +++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp @@ -14,13 +14,14 @@ */ #include "LauncherPartLaunch.h" -#include <QCoreApplication> -#include <launch/LaunchTask.h> -#include <minecraft/MinecraftInstance.h> -#include <FileSystem.h> -#include <Commandline.h> + #include <QStandardPaths> -#include "Env.h" + +#include "launch/LaunchTask.h" +#include "minecraft/MinecraftInstance.h" +#include "FileSystem.h" +#include "Commandline.h" +#include "Application.h" LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent) { @@ -72,7 +73,7 @@ void LauncherPartLaunch::executeTask() m_process.setDetachable(true); auto classPath = minecraftInstance->getClassPath(); - classPath.prepend(FS::PathCombine(ENV.getJarsPath(), "NewLaunch.jar")); + classPath.prepend(FS::PathCombine(APPLICATION->getJarsPath(), "NewLaunch.jar")); auto natPath = minecraftInstance->getNativePath(); #ifdef Q_OS_WIN diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 657669af..d9f7ecdc 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -11,8 +11,17 @@ void VerifyJavaInstall::executeTask() { auto javaVersion = m_inst->getJavaVersion(); auto minecraftComponent = m_inst->getPackProfile()->getComponent("net.minecraft"); + // Java 17 requirement + if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java17BeginsDate) { + if (javaVersion.major() < 17) { + emit logLine("Minecraft 1.18 Pre Release 2 and above require the use of Java 17", + MessageLevel::Fatal); + emitFailed(tr("Minecraft 1.18 Pre Release 2 and above require the use of Java 17")); + return; + } + } // Java 16 requirement - if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) { + else if (minecraftComponent->getReleaseDateTime() >= g_VersionFilterData.java16BeginsDate) { if (javaVersion.major() < 16) { emit logLine("Minecraft 21w19a and above require the use of Java 16", MessageLevel::Fatal); diff --git a/launcher/minecraft/legacy/LegacyInstance.cpp b/launcher/minecraft/legacy/LegacyInstance.cpp index 9f9bda5a..c2b4309c 100644 --- a/launcher/minecraft/legacy/LegacyInstance.cpp +++ b/launcher/minecraft/legacy/LegacyInstance.cpp @@ -90,7 +90,7 @@ bool LegacyInstance::shouldUseCustomBaseJar() const } -shared_qobject_ptr<Task> LegacyInstance::createUpdateTask(Net::Mode) +Task::Ptr LegacyInstance::createUpdateTask(Net::Mode) { return nullptr; } diff --git a/launcher/minecraft/legacy/LegacyInstance.h b/launcher/minecraft/legacy/LegacyInstance.h index ac2a8543..c6680fd0 100644 --- a/launcher/minecraft/legacy/LegacyInstance.h +++ b/launcher/minecraft/legacy/LegacyInstance.h @@ -93,7 +93,7 @@ public: }; virtual bool shouldUpdate() const; - virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override; + virtual Task::Ptr createUpdateTask(Net::Mode mode) override; virtual QString typeName() const override; diff --git a/launcher/minecraft/services/CapeChange.cpp b/launcher/minecraft/services/CapeChange.cpp index c1d88d14..d411965a 100644 --- a/launcher/minecraft/services/CapeChange.cpp +++ b/launcher/minecraft/services/CapeChange.cpp @@ -1,7 +1,9 @@ #include "CapeChange.h" + #include <QNetworkRequest> #include <QHttpMultiPart> -#include <Env.h> + +#include "Application.h" CapeChange::CapeChange(QObject *parent, AuthSessionPtr session, QString cape) : Task(parent), m_capeId(cape), m_session(session) @@ -12,11 +14,11 @@ void CapeChange::setCape(QString& cape) { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.qnam().put(request, requestString.toUtf8()); + QNetworkReply *rep = APPLICATION->network()->put(request, requestString.toUtf8()); setStatus(tr("Equipping cape")); - m_reply = std::shared_ptr<QNetworkReply>(rep); + m_reply = shared_qobject_ptr<QNetworkReply>(rep); connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError))); connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished())); @@ -26,11 +28,11 @@ void CapeChange::clearCape() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active")); auto requestString = QString("{\"capeId\":\"%1\"}").arg(m_capeId); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.qnam().deleteResource(request); + QNetworkReply *rep = APPLICATION->network()->deleteResource(request); setStatus(tr("Removing cape")); - m_reply = std::shared_ptr<QNetworkReply>(rep); + m_reply = shared_qobject_ptr<QNetworkReply>(rep); connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError))); connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished())); diff --git a/launcher/minecraft/services/CapeChange.h b/launcher/minecraft/services/CapeChange.h index 1b6f2f72..c04ad8c7 100644 --- a/launcher/minecraft/services/CapeChange.h +++ b/launcher/minecraft/services/CapeChange.h @@ -5,6 +5,7 @@ #include <memory> #include <minecraft/auth/AuthSession.h> #include "tasks/Task.h" +#include "QObjectPtr.h" class CapeChange : public Task { @@ -20,7 +21,7 @@ private: private: QString m_capeId; AuthSessionPtr m_session; - std::shared_ptr<QNetworkReply> m_reply; + shared_qobject_ptr<QNetworkReply> m_reply; protected: virtual void executeTask(); diff --git a/launcher/minecraft/services/SkinDelete.cpp b/launcher/minecraft/services/SkinDelete.cpp index 34977257..a0b0330c 100644 --- a/launcher/minecraft/services/SkinDelete.cpp +++ b/launcher/minecraft/services/SkinDelete.cpp @@ -1,7 +1,9 @@ #include "SkinDelete.h" + #include <QNetworkRequest> #include <QHttpMultiPart> -#include <Env.h> + +#include "Application.h" SkinDelete::SkinDelete(QObject *parent, AuthSessionPtr session) : Task(parent), m_session(session) @@ -12,8 +14,8 @@ void SkinDelete::executeTask() { QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/skins/active")); request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit()); - QNetworkReply *rep = ENV.qnam().deleteResource(request); - m_reply = std::shared_ptr<QNetworkReply>(rep); + QNetworkReply *rep = APPLICATION->network()->deleteResource(request); + m_reply = shared_qobject_ptr<QNetworkReply>(rep); setStatus(tr("Deleting skin")); connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); diff --git a/launcher/minecraft/services/SkinDelete.h b/launcher/minecraft/services/SkinDelete.h index 839bf9bc..6048b33a 100644 --- a/launcher/minecraft/services/SkinDelete.h +++ b/launcher/minecraft/services/SkinDelete.h @@ -2,11 +2,10 @@ #include <QFile> #include <QtNetwork/QtNetwork> -#include <memory> #include <minecraft/auth/AuthSession.h> #include "tasks/Task.h" -typedef std::shared_ptr<class SkinDelete> SkinDeletePtr; +typedef shared_qobject_ptr<class SkinDelete> SkinDeletePtr; class SkinDelete : public Task { @@ -17,7 +16,7 @@ public: private: AuthSessionPtr m_session; - std::shared_ptr<QNetworkReply> m_reply; + shared_qobject_ptr<QNetworkReply> m_reply; protected: virtual void executeTask(); diff --git a/launcher/minecraft/services/SkinUpload.cpp b/launcher/minecraft/services/SkinUpload.cpp index 4e5a1698..e58d32d7 100644 --- a/launcher/minecraft/services/SkinUpload.cpp +++ b/launcher/minecraft/services/SkinUpload.cpp @@ -1,7 +1,9 @@ #include "SkinUpload.h" + #include <QNetworkRequest> #include <QHttpMultiPart> -#include <Env.h> + +#include "Application.h" QByteArray getVariant(SkinUpload::Model model) { switch (model) { @@ -37,8 +39,8 @@ void SkinUpload::executeTask() multiPart->append(skin); multiPart->append(model); - QNetworkReply *rep = ENV.qnam().post(request, multiPart); - m_reply = std::shared_ptr<QNetworkReply>(rep); + QNetworkReply *rep = APPLICATION->network()->post(request, multiPart); + m_reply = shared_qobject_ptr<QNetworkReply>(rep); setStatus(tr("Uploading skin")); connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); diff --git a/launcher/minecraft/services/SkinUpload.h b/launcher/minecraft/services/SkinUpload.h index ec859699..2c782e11 100644 --- a/launcher/minecraft/services/SkinUpload.h +++ b/launcher/minecraft/services/SkinUpload.h @@ -6,7 +6,7 @@ #include <minecraft/auth/AuthSession.h> #include "tasks/Task.h" -typedef std::shared_ptr<class SkinUpload> SkinUploadPtr; +typedef shared_qobject_ptr<class SkinUpload> SkinUploadPtr; class SkinUpload : public Task { @@ -26,7 +26,7 @@ private: Model m_model; QByteArray m_skin; AuthSessionPtr m_session; - std::shared_ptr<QNetworkReply> m_reply; + shared_qobject_ptr<QNetworkReply> m_reply; protected: virtual void executeTask(); diff --git a/launcher/minecraft/update/AssetUpdateTask.cpp b/launcher/minecraft/update/AssetUpdateTask.cpp index e26ab4ef..096e1719 100644 --- a/launcher/minecraft/update/AssetUpdateTask.cpp +++ b/launcher/minecraft/update/AssetUpdateTask.cpp @@ -1,10 +1,12 @@ -#include "Env.h" #include "AssetUpdateTask.h" + #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include "net/ChecksumValidator.h" #include "minecraft/AssetsUtils.h" +#include "Application.h" + AssetUpdateTask::AssetUpdateTask(MinecraftInstance * inst) { m_inst = inst; @@ -24,7 +26,7 @@ void AssetUpdateTask::executeTask() QString localPath = assets->id + ".json"; auto job = new NetJob(tr("Asset index for %1").arg(m_inst->name())); - auto metacache = ENV.metacache(); + auto metacache = APPLICATION->metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); entry->setStale(true); auto hexSha1 = assets->sha1.toLatin1(); @@ -41,7 +43,7 @@ void AssetUpdateTask::executeTask() connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); qDebug() << m_inst->name() << ": Starting asset index download"; - downloadJob->start(); + downloadJob->start(APPLICATION->network()); } bool AssetUpdateTask::canAbort() const @@ -62,7 +64,7 @@ void AssetUpdateTask::assetIndexFinished() // FIXME: this looks like a job for a generic validator based on json schema? if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, index)) { - auto metacache = ENV.metacache(); + auto metacache = APPLICATION->metacache(); auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json"); metacache->evictEntry(entry); emitFailed(tr("Failed to read the assets index!")); @@ -76,7 +78,7 @@ void AssetUpdateTask::assetIndexFinished() connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded); connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed); connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress); - downloadJob->start(); + downloadJob->start(APPLICATION->network()); return; } emitSucceeded(); diff --git a/launcher/minecraft/update/AssetUpdateTask.h b/launcher/minecraft/update/AssetUpdateTask.h index fdfa8f1c..6d7356f3 100644 --- a/launcher/minecraft/update/AssetUpdateTask.h +++ b/launcher/minecraft/update/AssetUpdateTask.h @@ -24,5 +24,5 @@ public slots: private: MinecraftInstance *m_inst; - NetJobPtr downloadJob; + NetJob::Ptr downloadJob; }; diff --git a/launcher/minecraft/update/FMLLibrariesTask.cpp b/launcher/minecraft/update/FMLLibrariesTask.cpp index 8f1a43ff..a5c6b1e3 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.cpp +++ b/launcher/minecraft/update/FMLLibrariesTask.cpp @@ -1,10 +1,12 @@ -#include "Env.h" -#include <FileSystem.h> -#include <minecraft/VersionFilterData.h> #include "FMLLibrariesTask.h" + +#include "FileSystem.h" +#include "minecraft/VersionFilterData.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" + #include "BuildConfig.h" +#include "Application.h" FMLLibrariesTask::FMLLibrariesTask(MinecraftInstance * inst) { @@ -60,7 +62,7 @@ void FMLLibrariesTask::executeTask() // download missing libs to our place setStatus(tr("Downloading FML libraries...")); auto dljob = new NetJob("FML libraries"); - auto metacache = ENV.metacache(); + auto metacache = APPLICATION->metacache(); for (auto &lib : fmlLibsToProcess) { auto entry = metacache->resolveEntry("fmllibs", lib.filename); @@ -72,7 +74,7 @@ void FMLLibrariesTask::executeTask() connect(dljob, &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed); connect(dljob, &NetJob::progress, this, &FMLLibrariesTask::progress); downloadJob.reset(dljob); - downloadJob->start(); + downloadJob->start(APPLICATION->network()); } bool FMLLibrariesTask::canAbort() const @@ -87,7 +89,7 @@ void FMLLibrariesTask::fmllibsFinished() { setStatus(tr("Copying FML libraries into the instance...")); MinecraftInstance *inst = (MinecraftInstance *)m_inst; - auto metacache = ENV.metacache(); + auto metacache = APPLICATION->metacache(); int index = 0; for (auto &lib : fmlLibsToProcess) { diff --git a/launcher/minecraft/update/FMLLibrariesTask.h b/launcher/minecraft/update/FMLLibrariesTask.h index a1e70ed4..2e5ad83a 100644 --- a/launcher/minecraft/update/FMLLibrariesTask.h +++ b/launcher/minecraft/update/FMLLibrariesTask.h @@ -25,7 +25,7 @@ public slots: private: MinecraftInstance *m_inst; - NetJobPtr downloadJob; + NetJob::Ptr downloadJob; QList<FMLlib> fmlLibsToProcess; }; diff --git a/launcher/minecraft/update/LibrariesTask.cpp b/launcher/minecraft/update/LibrariesTask.cpp index 7f66a651..065b4e06 100644 --- a/launcher/minecraft/update/LibrariesTask.cpp +++ b/launcher/minecraft/update/LibrariesTask.cpp @@ -1,8 +1,10 @@ -#include "Env.h" #include "LibrariesTask.h" + #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "Application.h" + LibrariesTask::LibrariesTask(MinecraftInstance * inst) { m_inst = inst; @@ -21,7 +23,7 @@ void LibrariesTask::executeTask() auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); downloadJob.reset(job); - auto metacache = ENV.metacache(); + auto metacache = APPLICATION->metacache(); auto processArtifactPool = [&](const QList<LibraryPtr> & pool, QStringList & errors, const QString & localPath) { @@ -63,7 +65,7 @@ void LibrariesTask::executeTask() connect(downloadJob.get(), &NetJob::succeeded, this, &LibrariesTask::emitSucceeded); connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed); connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress); - downloadJob->start(); + downloadJob->start(APPLICATION->network()); } bool LibrariesTask::canAbort() const diff --git a/launcher/minecraft/update/LibrariesTask.h b/launcher/minecraft/update/LibrariesTask.h index 49f76932..b966ad6c 100644 --- a/launcher/minecraft/update/LibrariesTask.h +++ b/launcher/minecraft/update/LibrariesTask.h @@ -22,5 +22,5 @@ public slots: private: MinecraftInstance *m_inst; - NetJobPtr downloadJob; + NetJob::Ptr downloadJob; }; diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 55087a27..9ef32db1 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -1,13 +1,13 @@ -#include <Env.h> -#include <quazip.h> -#include <QtConcurrent/QtConcurrent> -#include <MMCZip.h> -#include <minecraft/OneSixVersionFormat.h> -#include <Version.h> -#include <net/ChecksumValidator.h> #include "ATLPackInstallTask.h" -#include "BuildConfig.h" +#include <QtConcurrent/QtConcurrent> + +#include <quazip.h> + +#include "MMCZip.h" +#include "minecraft/OneSixVersionFormat.h" +#include "Version.h" +#include "net/ChecksumValidator.h" #include "FileSystem.h" #include "Json.h" #include "minecraft/MinecraftInstance.h" @@ -17,6 +17,9 @@ #include "meta/Version.h" #include "meta/VersionList.h" +#include "BuildConfig.h" +#include "Application.h" + namespace ATLauncher { PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString pack, QString version) @@ -43,7 +46,7 @@ void PackInstallTask::executeTask() .arg(m_pack).arg(m_version_name); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed); @@ -76,7 +79,7 @@ void PackInstallTask::onDownloadSucceeded() } m_version = version; - auto vlist = ENV.metadataIndex()->get("net.minecraft"); + auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); if(!vlist) { emitFailed(tr("Failed to get local metadata index for %1").arg("net.minecraft")); @@ -157,7 +160,7 @@ QString PackInstallTask::getDirForModType(ModType type, QString raw) QString PackInstallTask::getVersionForLoader(QString uid) { if(m_version.loader.recommended || m_version.loader.latest || m_version.loader.choose) { - auto vlist = ENV.metadataIndex()->get(uid); + auto vlist = APPLICATION->metadataIndex()->get(uid); if(!vlist) { emitFailed(tr("Failed to get local metadata index for %1").arg(uid)); @@ -409,7 +412,7 @@ void PackInstallTask::installConfigs() auto path = QString("Configs/%1/%2.zip").arg(m_pack).arg(m_version_name); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip") .arg(m_pack).arg(m_version_name); - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", path); + auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", path); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); @@ -438,7 +441,7 @@ void PackInstallTask::installConfigs() setProgress(current, total); }); - jobPtr->start(); + jobPtr->start(APPLICATION->network()); } void PackInstallTask::extractConfigs() @@ -516,7 +519,7 @@ void PackInstallTask::downloadMods() auto cacheName = fileName.completeBaseName() + "-" + mod.md5 + "." + fileName.suffix(); if (mod.type == ModType::Extract || mod.type == ModType::TexturePackExtract || mod.type == ModType::ResourcePackExtract) { - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToExtract.insert(entry->getFullPath(), mod); @@ -528,7 +531,7 @@ void PackInstallTask::downloadMods() jobPtr->addNetAction(dl); } else if(mod.type == ModType::Decomp) { - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToDecomp.insert(entry->getFullPath(), mod); @@ -543,7 +546,7 @@ void PackInstallTask::downloadMods() auto relpath = getDirForModType(mod.type, mod.type_raw); if(relpath == Q_NULLPTR) continue; - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); + auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); auto dl = Net::Download::makeCached(url, entry); @@ -558,7 +561,7 @@ void PackInstallTask::downloadMods() modsToCopy[entry->getFullPath()] = path; if(mod.type == ModType::Forge) { - auto vlist = ENV.metadataIndex()->get("net.minecraftforge"); + auto vlist = APPLICATION->metadataIndex()->get("net.minecraftforge"); if(vlist) { auto ver = vlist->getVersion(mod.version); @@ -593,7 +596,7 @@ void PackInstallTask::downloadMods() setProgress(current, total); }); - jobPtr->start(); + jobPtr->start(APPLICATION->network()); } void PackInstallTask::onModsDownloaded() { diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index 39e2b013..f8ea2d54 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -74,7 +74,7 @@ private: bool abortable = false; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; QByteArray response; QString m_pack; diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 295574f0..06f0cf2b 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -5,8 +5,8 @@ namespace { const char * metabase = "https://cursemeta.dries007.net"; } -Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess) - : m_toProcess(toProcess) +Flame::FileResolvingTask::FileResolvingTask(shared_qobject_ptr<QNetworkAccessManager> network, Flame::Manifest& toProcess) + : m_network(network), m_toProcess(toProcess) { } @@ -14,7 +14,7 @@ void Flame::FileResolvingTask::executeTask() { setStatus(tr("Resolving mod IDs...")); setProgress(0, m_toProcess.files.size()); - m_dljob.reset(new NetJob("Mod id resolver")); + m_dljob = new NetJob("Mod id resolver"); results.resize(m_toProcess.files.size()); int index = 0; for(auto & file: m_toProcess.files) @@ -27,7 +27,7 @@ void Flame::FileResolvingTask::executeTask() index ++; } connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished); - m_dljob->start(); + m_dljob->start(m_network); } void Flame::FileResolvingTask::netJobFinished() diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h index 78a38fcb..5e5adcd7 100644 --- a/launcher/modplatform/flame/FileResolvingTask.h +++ b/launcher/modplatform/flame/FileResolvingTask.h @@ -10,7 +10,7 @@ class FileResolvingTask : public Task { Q_OBJECT public: - explicit FileResolvingTask(Flame::Manifest &toProcess); + explicit FileResolvingTask(shared_qobject_ptr<QNetworkAccessManager> network, Flame::Manifest &toProcess); virtual ~FileResolvingTask() {}; const Flame::Manifest &getResults() const @@ -25,8 +25,9 @@ protected slots: void netJobFinished(); private: /* data */ + shared_qobject_ptr<QNetworkAccessManager> m_network; Flame::Manifest m_toProcess; QVector<QByteArray> results; - NetJobPtr m_dljob; + NetJob::Ptr m_dljob; }; } diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp index c2ef6436..ecf36188 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.cpp @@ -2,7 +2,8 @@ #include "PrivatePackManager.h" #include <QDomDocument> -#include <BuildConfig.h> +#include "BuildConfig.h" +#include "Application.h" namespace LegacyFTB { @@ -11,21 +12,20 @@ void PackFetchTask::fetch() publicPacks.clear(); thirdPartyPacks.clear(); - NetJob *netJob = new NetJob("LegacyFTB::ModpackFetch"); + jobPtr = new NetJob("LegacyFTB::ModpackFetch"); QUrl publicPacksUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml"); qDebug() << "Downloading public version info from" << publicPacksUrl.toString(); - netJob->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData)); + jobPtr->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData)); QUrl thirdPartyUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/thirdparty.xml"); qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString(); - netJob->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData)); + jobPtr->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData)); - QObject::connect(netJob, &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished); - QObject::connect(netJob, &NetJob::failed, this, &PackFetchTask::fileDownloadFailed); + QObject::connect(jobPtr.get(), &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished); + QObject::connect(jobPtr.get(), &NetJob::failed, this, &PackFetchTask::fileDownloadFailed); - jobPtr.reset(netJob); - netJob->start(); + jobPtr->start(m_network); } void PackFetchTask::fetchPrivate(const QStringList & toFetch) @@ -63,7 +63,7 @@ void PackFetchTask::fetchPrivate(const QStringList & toFetch) delete data; }); - job->start(); + job->start(m_network); } } diff --git a/launcher/modplatform/legacy_ftb/PackFetchTask.h b/launcher/modplatform/legacy_ftb/PackFetchTask.h index 3ab32fab..f1667e90 100644 --- a/launcher/modplatform/legacy_ftb/PackFetchTask.h +++ b/launcher/modplatform/legacy_ftb/PackFetchTask.h @@ -13,14 +13,15 @@ class PackFetchTask : public QObject { Q_OBJECT public: - PackFetchTask() = default; + PackFetchTask(shared_qobject_ptr<QNetworkAccessManager> network) : QObject(nullptr), m_network(network) {}; virtual ~PackFetchTask() = default; void fetch(); void fetchPrivate(const QStringList &toFetch); private: - NetJobPtr jobPtr; + shared_qobject_ptr<QNetworkAccessManager> m_network; + NetJob::Ptr jobPtr; QByteArray publicModpacksXmlFileData; QByteArray thirdPartyModpacksXmlFileData; diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index c77f3250..64aecb39 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -1,24 +1,25 @@ #include "PackInstallTask.h" -#include "Env.h" -#include "MMCZip.h" +#include <QtConcurrent> +#include "MMCZip.h" #include "BaseInstance.h" #include "FileSystem.h" #include "settings/INISettingsObject.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include "minecraft/GradleSpecifier.h" -#include "BuildConfig.h" -#include <QtConcurrent> +#include "BuildConfig.h" +#include "Application.h" namespace LegacyFTB { -PackInstallTask::PackInstallTask(Modpack pack, QString version) +PackInstallTask::PackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, Modpack pack, QString version) { m_pack = pack; m_version = version; + m_network = network; } void PackInstallTask::executeTask() @@ -31,8 +32,8 @@ void PackInstallTask::downloadPack() setStatus(tr("Downloading zip for %1").arg(m_pack.name)); auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file); - auto entry = ENV.metacache()->resolveEntry("FTBPacks", packoffset); - NetJob *job = new NetJob("Download FTB Pack"); + auto entry = APPLICATION->metacache()->resolveEntry("FTBPacks", packoffset); + netJobContainer = new NetJob("Download FTB Pack"); entry->setStale(true); QString url; @@ -44,14 +45,13 @@ void PackInstallTask::downloadPack() { url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(packoffset); } - job->addNetAction(Net::Download::makeCached(url, entry)); + netJobContainer->addNetAction(Net::Download::makeCached(url, entry)); archivePath = entry->getFullPath(); - netJobContainer.reset(job); - connect(job, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); - connect(job, &NetJob::failed, this, &PackInstallTask::onDownloadFailed); - connect(job, &NetJob::progress, this, &PackInstallTask::onDownloadProgress); - job->start(); + connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); + connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed); + connect(netJobContainer.get(), &NetJob::progress, this, &PackInstallTask::onDownloadProgress); + netJobContainer->start(m_network); progress(1, 4); } diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.h b/launcher/modplatform/legacy_ftb/PackInstallTask.h index 600f72e7..305635a1 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.h +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.h @@ -8,6 +8,8 @@ #include "meta/VersionList.h" #include "PackHelpers.h" +#include "net/NetJob.h" + #include <nonstd/optional> namespace LegacyFTB { @@ -17,7 +19,7 @@ class PackInstallTask : public InstanceTask Q_OBJECT public: - explicit PackInstallTask(Modpack pack, QString version); + explicit PackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, Modpack pack, QString version); virtual ~PackInstallTask(){} bool canAbort() const override { return true; } @@ -41,11 +43,12 @@ private slots: void onUnzipCanceled(); private: /* data */ + shared_qobject_ptr<QNetworkAccessManager> m_network; bool abortable = false; std::unique_ptr<QuaZip> m_packZip; QFuture<nonstd::optional<QStringList>> m_extractFuture; QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher; - NetJobPtr netJobContainer; + NetJob::Ptr netJobContainer; QString archivePath; Modpack m_pack; diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 496edde7..563b5cfa 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -1,7 +1,5 @@ #include "FTBPackInstallTask.h" -#include "BuildConfig.h" -#include "Env.h" #include "FileSystem.h" #include "Json.h" #include "minecraft/MinecraftInstance.h" @@ -9,6 +7,9 @@ #include "net/ChecksumValidator.h" #include "settings/INISettingsObject.h" +#include "BuildConfig.h" +#include "Application.h" + namespace ModpacksCH { PackInstallTask::PackInstallTask(Modpack pack, QString version) @@ -50,7 +51,7 @@ void PackInstallTask::executeTask() .arg(m_pack.id).arg(version.id); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded); QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed); @@ -95,14 +96,14 @@ void PackInstallTask::downloadPack() { setStatus(tr("Downloading mods...")); - jobPtr.reset(new NetJob(tr("Mod download"))); + jobPtr = new NetJob(tr("Mod download")); for(auto file : m_version.files) { if(file.serverOnly) continue; QFileInfo fileName(file.name); auto cacheName = fileName.completeBaseName() + "-" + file.sha1 + "." + fileName.suffix(); - auto entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", cacheName); + auto entry = APPLICATION->metacache()->resolveEntry("ModpacksCHPacks", cacheName); entry->setStale(true); auto relpath = FS::PathCombine("minecraft", file.path, file.name); @@ -141,7 +142,7 @@ void PackInstallTask::downloadPack() setProgress(current, total); }); - jobPtr->start(); + jobPtr->start(APPLICATION->network()); } void PackInstallTask::install() diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.h b/launcher/modplatform/modpacksch/FTBPackInstallTask.h index fdd84c4e..23362dc9 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.h +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.h @@ -32,7 +32,7 @@ private: private: bool abortable = false; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; QByteArray response; Modpack m_pack; diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp index dbce8e53..0ab9f3c0 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp @@ -15,12 +15,13 @@ #include "SingleZipPackInstallTask.h" -#include "Env.h" +#include <QtConcurrent> + #include "MMCZip.h" #include "TechnicPackProcessor.h" +#include "FileSystem.h" -#include <QtConcurrent> -#include <FileSystem.h> +#include "Application.h" Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion) { @@ -41,7 +42,7 @@ void Technic::SingleZipPackInstallTask::executeTask() setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path(); - auto entry = ENV.metacache()->resolveEntry("general", path); + auto entry = APPLICATION->metacache()->resolveEntry("general", path); entry->setStale(true); m_filesNetJob.reset(new NetJob(tr("Modpack download"))); m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); @@ -50,7 +51,7 @@ void Technic::SingleZipPackInstallTask::executeTask() connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded); connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged); connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed); - m_filesNetJob->start(); + m_filesNetJob->start(APPLICATION->network()); } void Technic::SingleZipPackInstallTask::downloadSucceeded() diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.h b/launcher/modplatform/technic/SingleZipPackInstallTask.h index 80f10a98..74f60941 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.h +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.h @@ -55,7 +55,7 @@ private: QUrl m_sourceUrl; QString m_minecraftVersion; QString m_archivePath; - NetJobPtr m_filesNetJob; + NetJob::Ptr m_filesNetJob; std::unique_ptr<QuaZip> m_packZip; QFuture<nonstd::optional<QStringList>> m_extractFuture; QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher; diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index 1b4186d4..2492ee81 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -21,10 +21,14 @@ #include <MMCZip.h> #include "TechnicPackProcessor.h" -Technic::SolderPackInstallTask::SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion) -{ +Technic::SolderPackInstallTask::SolderPackInstallTask( + shared_qobject_ptr<QNetworkAccessManager> network, + const QUrl &sourceUrl, + const QString &minecraftVersion +) { m_sourceUrl = sourceUrl; m_minecraftVersion = minecraftVersion; + m_network = network; } bool Technic::SolderPackInstallTask::abort() { @@ -43,7 +47,7 @@ void Technic::SolderPackInstallTask::executeTask() auto job = m_filesNetJob.get(); connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::versionSucceeded); connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed); - m_filesNetJob->start(); + m_filesNetJob->start(m_network); } void Technic::SolderPackInstallTask::versionSucceeded() @@ -68,7 +72,7 @@ void Technic::SolderPackInstallTask::versionSucceeded() auto job = m_filesNetJob.get(); connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded); connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed); - m_filesNetJob->start(); + m_filesNetJob->start(m_network); } void Technic::SolderPackInstallTask::fileListSucceeded() @@ -109,7 +113,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded() connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged); connect(m_filesNetJob.get(), &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed); - m_filesNetJob->start(); + m_filesNetJob->start(m_network); } void Technic::SolderPackInstallTask::downloadSucceeded() diff --git a/launcher/modplatform/technic/SolderPackInstallTask.h b/launcher/modplatform/technic/SolderPackInstallTask.h index 6e1057eb..9b2058d8 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.h +++ b/launcher/modplatform/technic/SolderPackInstallTask.h @@ -27,7 +27,7 @@ namespace Technic { Q_OBJECT public: - explicit SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion); + explicit SolderPackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, const QUrl &sourceUrl, const QString &minecraftVersion); bool canAbort() const override { return true; } bool abort() override; @@ -48,7 +48,9 @@ namespace Technic private: bool m_abortable = false; - NetJobPtr m_filesNetJob; + shared_qobject_ptr<QNetworkAccessManager> m_network; + + NetJob::Ptr m_filesNetJob; QUrl m_sourceUrl; QString m_minecraftVersion; QByteArray m_response; diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index 3f183b7d..b314573f 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -15,16 +15,17 @@ #include "Download.h" -#include "BuildConfig.h" #include <QFileInfo> #include <QDateTime> #include <QDebug> -#include "Env.h" -#include <FileSystem.h> + +#include "FileSystem.h" #include "ChecksumValidator.h" #include "MetaCacheSink.h" #include "ByteArraySink.h" +#include "BuildConfig.h" + namespace Net { Download::Download():NetAction() @@ -41,7 +42,7 @@ Download::Ptr Download::makeCached(QUrl url, MetaEntryPtr entry, Options options auto cachedNode = new MetaCacheSink(entry, md5Node); dl->m_sink.reset(cachedNode); dl->m_target_path = entry->getFullPath(); - return std::shared_ptr<Download>(dl); + return dl; } Download::Ptr Download::makeByteArray(QUrl url, QByteArray *output, Options options) @@ -50,7 +51,7 @@ Download::Ptr Download::makeByteArray(QUrl url, QByteArray *output, Options opti dl->m_url = url; dl->m_options = options; dl->m_sink.reset(new ByteArraySink(output)); - return std::shared_ptr<Download>(dl); + return dl; } Download::Ptr Download::makeFile(QUrl url, QString path, Options options) @@ -59,7 +60,7 @@ Download::Ptr Download::makeFile(QUrl url, QString path, Options options) dl->m_url = url; dl->m_options = options; dl->m_sink.reset(new FileSink(path)); - return std::shared_ptr<Download>(dl); + return dl; } void Download::addValidator(Validator * v) @@ -67,7 +68,7 @@ void Download::addValidator(Validator * v) m_sink->addValidator(v); } -void Download::start() +void Download::startImpl() { if(m_status == Job_Aborted) { @@ -97,7 +98,7 @@ void Download::start() request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT); - QNetworkReply *rep = ENV.qnam().get(request); + QNetworkReply *rep = m_network->get(request); m_reply.reset(rep); connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64))); @@ -207,7 +208,7 @@ bool Download::handleRedirect() m_url = QUrl(redirect.toString()); qDebug() << "Following redirect to " << m_url.toString(); - start(); + start(m_network); return true; } diff --git a/launcher/net/Download.h b/launcher/net/Download.h index a224bb86..0f9bfe7f 100644 --- a/launcher/net/Download.h +++ b/launcher/net/Download.h @@ -20,13 +20,15 @@ #include "Validator.h" #include "Sink.h" +#include "QObjectPtr.h" + namespace Net { class Download : public NetAction { Q_OBJECT public: /* types */ - typedef std::shared_ptr<class Download> Ptr; + typedef shared_qobject_ptr<class Download> Ptr; enum class Option { NoOptions = 0, @@ -62,7 +64,7 @@ protected slots: void downloadReadyRead() override; public slots: - void start() override; + void startImpl() override; private: /* data */ // FIXME: remove this, it has no business being here. diff --git a/launcher/net/FileSink.cpp b/launcher/net/FileSink.cpp index 8b3e917d..7e9b8929 100644 --- a/launcher/net/FileSink.cpp +++ b/launcher/net/FileSink.cpp @@ -1,7 +1,6 @@ #include "FileSink.h" #include <QFile> #include <QFileInfo> -#include "Env.h" #include "FileSystem.h" namespace Net { diff --git a/launcher/net/HttpMetaCache.cpp b/launcher/net/HttpMetaCache.cpp index 4bc8fbc8..8734e0bf 100644 --- a/launcher/net/HttpMetaCache.cpp +++ b/launcher/net/HttpMetaCache.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "Env.h" #include "HttpMetaCache.h" #include "FileSystem.h" diff --git a/launcher/net/MetaCacheSink.cpp b/launcher/net/MetaCacheSink.cpp index d7f18533..5cdf0460 100644 --- a/launcher/net/MetaCacheSink.cpp +++ b/launcher/net/MetaCacheSink.cpp @@ -1,8 +1,8 @@ #include "MetaCacheSink.h" #include <QFile> #include <QFileInfo> -#include "Env.h" #include "FileSystem.h" +#include "Application.h" namespace Net { @@ -53,7 +53,7 @@ JobStatus MetaCacheSink::finalizeCache(QNetworkReply & reply) } m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); m_entry->setStale(false); - ENV.metacache()->updateEntry(m_entry); + APPLICATION->metacache()->updateEntry(m_entry); return Job_Finished; } diff --git a/launcher/net/NetAction.h b/launcher/net/NetAction.h index c13c187f..efb20953 100644 --- a/launcher/net/NetAction.h +++ b/launcher/net/NetAction.h @@ -35,14 +35,15 @@ enum JobStatus Job_Failed_Proceed }; -typedef std::shared_ptr<class NetAction> NetActionPtr; class NetAction : public QObject { Q_OBJECT protected: - explicit NetAction() : QObject(0) {}; + explicit NetAction() : QObject(nullptr) {}; public: + using Ptr = shared_qobject_ptr<NetAction>; + virtual ~NetAction() {}; bool isRunning() const @@ -93,9 +94,17 @@ protected slots: virtual void downloadReadyRead() = 0; public slots: - virtual void start() = 0; + void start(shared_qobject_ptr<QNetworkAccessManager> network) { + m_network = network; + startImpl(); + } + +protected: + virtual void startImpl() = 0; public: + shared_qobject_ptr<QNetworkAccessManager> m_network; + /// index within the parent job, FIXME: nuke int m_index_within_job = 0; diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 029d9e34..9bad89ed 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -144,7 +144,7 @@ void NetJob::startMoreParts() connect(part.get(), SIGNAL(aborted(int)), SLOT(partAborted(int))); connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)), SLOT(partProgress(int, qint64, qint64))); - part->start(); + part->start(m_network); } } @@ -194,7 +194,7 @@ bool NetJob::abort() return fullyAborted; } -bool NetJob::addNetAction(NetActionPtr action) +bool NetJob::addNetAction(NetAction::Ptr action) { action->m_index_within_job = downloads.size(); downloads.append(action); diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h index 338f8e71..45b9bc0f 100644 --- a/launcher/net/NetJob.h +++ b/launcher/net/NetJob.h @@ -22,33 +22,34 @@ #include "QObjectPtr.h" class NetJob; -typedef shared_qobject_ptr<NetJob> NetJobPtr; class NetJob : public Task { Q_OBJECT public: + using Ptr = shared_qobject_ptr<NetJob>; + explicit NetJob(QString job_name) : Task() { setObjectName(job_name); } virtual ~NetJob(); - bool addNetAction(NetActionPtr action); + bool addNetAction(NetAction::Ptr action); - NetActionPtr operator[](int index) + NetAction::Ptr operator[](int index) { return downloads[index]; } - const NetActionPtr at(const int index) + const NetAction::Ptr at(const int index) { return downloads.at(index); } - NetActionPtr first() + NetAction::Ptr first() { if (downloads.size()) return downloads[0]; - return NetActionPtr(); + return NetAction::Ptr(); } int size() const { @@ -64,6 +65,19 @@ private slots: public slots: virtual void executeTask() override; virtual bool abort() override; + virtual void start(shared_qobject_ptr<QNetworkAccessManager> network) { + m_network = network; + start(); + } + +protected slots: + void start() override { + if(!m_network) { + throw "Missing network while trying to start " + objectName(); + return; + } + Task::start(); + } private slots: void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal); @@ -72,13 +86,15 @@ private slots: void partAborted(int index); private: + shared_qobject_ptr<QNetworkAccessManager> m_network; + struct part_info { qint64 current_progress = 0; qint64 total_progress = 1; int failures = 0; }; - QList<NetActionPtr> downloads; + QList<NetAction::Ptr> downloads; QList<part_info> parts_progress; QQueue<int> m_todo; QSet<int> m_doing; diff --git a/launcher/net/PasteUpload.cpp b/launcher/net/PasteUpload.cpp index 8ec6e4ae..4b69b68a 100644 --- a/launcher/net/PasteUpload.cpp +++ b/launcher/net/PasteUpload.cpp @@ -1,11 +1,12 @@ #include "PasteUpload.h" -#include "Env.h" +#include "BuildConfig.h" +#include "Application.h" + #include <QDebug> #include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> #include <QFile> -#include <BuildConfig.h> PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window) { @@ -41,7 +42,7 @@ void PasteUpload::executeTask() request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size())); request.setRawHeader("X-Auth-Token", m_key.toStdString().c_str()); - QNetworkReply *rep = ENV.qnam().post(request, m_jsonContent); + QNetworkReply *rep = APPLICATION->network()->post(request, m_jsonContent); m_reply = std::shared_ptr<QNetworkReply>(rep); setStatus(tr("Uploading to paste.ee")); diff --git a/launcher/news/NewsChecker.cpp b/launcher/news/NewsChecker.cpp index c66f49e1..77d428a5 100644 --- a/launcher/news/NewsChecker.cpp +++ b/launcher/news/NewsChecker.cpp @@ -20,8 +20,9 @@ #include <QDebug> -NewsChecker::NewsChecker(const QString& feedUrl) +NewsChecker::NewsChecker(shared_qobject_ptr<QNetworkAccessManager> network, const QString& feedUrl) { + m_network = network; m_feedUrl = feedUrl; } @@ -41,7 +42,7 @@ void NewsChecker::reloadNews() QObject::connect(job, &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished); QObject::connect(job, &NetJob::failed, this, &NewsChecker::rssDownloadFailed); m_newsNetJob.reset(job); - job->start(); + job->start(m_network); } void NewsChecker::rssDownloadFinished() diff --git a/launcher/news/NewsChecker.h b/launcher/news/NewsChecker.h index 84b1f552..8467a541 100644 --- a/launcher/news/NewsChecker.h +++ b/launcher/news/NewsChecker.h @@ -30,7 +30,7 @@ public: /*! * Constructs a news reader to read from the given RSS feed URL. */ - NewsChecker(const QString& feedUrl); + NewsChecker(shared_qobject_ptr<QNetworkAccessManager> network, const QString& feedUrl); /*! * Returns the error message for the last time the news was loaded. @@ -80,7 +80,7 @@ protected: /* data */ QList<NewsEntryPtr> m_newsEntries; //! The network job to use to load the news. - NetJobPtr m_newsNetJob; + NetJob::Ptr m_newsNetJob; //! True if news has been loaded. bool m_loadedNews; @@ -93,6 +93,8 @@ protected: /* data */ */ QString m_lastLoadError; + shared_qobject_ptr<QNetworkAccessManager> m_network; + protected slots: /// Emits newsLoaded() and sets m_lastLoadError to empty string. void succeed(); diff --git a/launcher/notifications/NotificationChecker.cpp b/launcher/notifications/NotificationChecker.cpp index 8209c28b..00c918f8 100644 --- a/launcher/notifications/NotificationChecker.cpp +++ b/launcher/notifications/NotificationChecker.cpp @@ -5,9 +5,9 @@ #include <QJsonArray> #include <QDebug> -#include "Env.h" #include "net/Download.h" +#include "Application.h" NotificationChecker::NotificationChecker(QObject *parent) : QObject(parent) @@ -53,11 +53,11 @@ void NotificationChecker::checkForNotifications() return; } m_checkJob.reset(new NetJob("Checking for notifications")); - auto entry = ENV.metacache()->resolveEntry("root", "notifications.json"); + auto entry = APPLICATION->metacache()->resolveEntry("root", "notifications.json"); entry->setStale(true); m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry)); connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded); - m_checkJob->start(); + m_checkJob->start(APPLICATION->network()); } void NotificationChecker::downloadSucceeded(int) diff --git a/launcher/notifications/NotificationChecker.h b/launcher/notifications/NotificationChecker.h index eb2b32a2..0f305f33 100644 --- a/launcher/notifications/NotificationChecker.h +++ b/launcher/notifications/NotificationChecker.h @@ -52,7 +52,7 @@ private: private: QList<NotificationEntry> m_entries; QUrl m_notificationsUrl; - NetJobPtr m_checkJob; + NetJob::Ptr m_checkJob; Net::Download::Ptr m_download; QString m_appVersionChannel; diff --git a/launcher/package/ubuntu/multimc/usr/share/man/man1/multimc.1 b/launcher/package/ubuntu/multimc/usr/share/man/man1/multimc.1 index b2031aa9..b4af25e3 100644 --- a/launcher/package/ubuntu/multimc/usr/share/man/man1/multimc.1 +++ b/launcher/package/ubuntu/multimc/usr/share/man/man1/multimc.1 @@ -2,12 +2,12 @@ .\" Title: multimc .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> -.\" Date: 10/21/2021 +.\" Date: 11/07/2021 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MULTIMC" "1" "10/21/2021" "\ \&" "\ \&" +.TH "MULTIMC" "1" "11/07/2021" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -66,6 +66,13 @@ Display help text and exit\&. .RS 4 Display program version and exit\&. .RE +.PP +\fB\-a, \-\-profile\fR=\fIPROFILE\fR +.RS 4 +Use the account specified by +\fIPROFILE\fR +(only valid in combination with \-\-launch)\&. +.RE .SH "EXIT STATUS" .PP \fB0\fR diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index 1f195f00..d5de302a 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -5,18 +5,18 @@ #include <QJsonObject> #include <QUrl> #include <QStringList> +#include <QDebug> #include "BuildConfig.h" -#include "Env.h" -#include <QDebug> +#include "Application.h" -ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenshotPtr> screenshots) : NetAction(), m_screenshots(screenshots) +ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenShot::Ptr> screenshots) : NetAction(), m_screenshots(screenshots) { m_url = BuildConfig.IMGUR_BASE_URL + "album.json"; m_status = Job_NotStarted; } -void ImgurAlbumCreation::start() +void ImgurAlbumCreation::startImpl() { m_status = Job_InProgress; QNetworkRequest request(m_url); @@ -33,7 +33,7 @@ void ImgurAlbumCreation::start() const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; - QNetworkReply *rep = ENV.qnam().post(request, data); + QNetworkReply *rep = APPLICATION->network()->post(request, data); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); diff --git a/launcher/screenshots/ImgurAlbumCreation.h b/launcher/screenshots/ImgurAlbumCreation.h index 954637e6..cb048a23 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -1,13 +1,14 @@ #pragma once #include "net/NetAction.h" #include "Screenshot.h" +#include "QObjectPtr.h" -typedef std::shared_ptr<class ImgurAlbumCreation> ImgurAlbumCreationPtr; +typedef shared_qobject_ptr<class ImgurAlbumCreation> ImgurAlbumCreationPtr; class ImgurAlbumCreation : public NetAction { public: - explicit ImgurAlbumCreation(QList<ScreenshotPtr> screenshots); - static ImgurAlbumCreationPtr make(QList<ScreenshotPtr> screenshots) + explicit ImgurAlbumCreation(QList<ScreenShot::Ptr> screenshots); + static ImgurAlbumCreationPtr make(QList<ScreenShot::Ptr> screenshots) { return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); } @@ -32,10 +33,10 @@ slots: public slots: - virtual void start(); + virtual void startImpl(); private: - QList<ScreenshotPtr> m_screenshots; + QList<ScreenShot::Ptr> m_screenshots; QString m_deleteHash; QString m_id; diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index 7e95d5ca..76a84947 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -1,4 +1,5 @@ #include "ImgurUpload.h" +#include "BuildConfig.h" #include <QNetworkRequest> #include <QHttpMultiPart> @@ -7,18 +8,15 @@ #include <QHttpPart> #include <QFile> #include <QUrl> - -#include "BuildConfig.h" -#include "Env.h" #include <QDebug> -ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot) +ImgurUpload::ImgurUpload(ScreenShot::Ptr shot) : NetAction(), m_shot(shot) { m_url = BuildConfig.IMGUR_BASE_URL + "upload.json"; m_status = Job_NotStarted; } -void ImgurUpload::start() +void ImgurUpload::startImpl() { finished = false; m_status = Job_InProgress; @@ -49,7 +47,7 @@ void ImgurUpload::start() namePart.setBody(m_shot->m_file.baseName().toUtf8()); multipart->append(namePart); - QNetworkReply *rep = ENV.qnam().post(request, multipart); + QNetworkReply *rep = m_network->post(request, multipart); m_reply.reset(rep); connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); diff --git a/launcher/screenshots/ImgurUpload.h b/launcher/screenshots/ImgurUpload.h index 0507d499..cf54f58d 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -1,31 +1,29 @@ #pragma once +#include "QObjectPtr.h" #include "net/NetAction.h" #include "Screenshot.h" -typedef std::shared_ptr<class ImgurUpload> ImgurUploadPtr; -class ImgurUpload : public NetAction -{ +class ImgurUpload : public NetAction { public: - explicit ImgurUpload(ScreenshotPtr shot); - static ImgurUploadPtr make(ScreenshotPtr shot) - { - return ImgurUploadPtr(new ImgurUpload(shot)); + using Ptr = shared_qobject_ptr<ImgurUpload>; + + explicit ImgurUpload(ScreenShot::Ptr shot); + static Ptr make(ScreenShot::Ptr shot) { + return Ptr(new ImgurUpload(shot)); } protected slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead() - { - } + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; + void downloadError(QNetworkReply::NetworkError error) override; + void downloadFinished() override; + void downloadReadyRead() override {} public slots: - virtual void start(); + void startImpl() override; private: - ScreenshotPtr m_shot; + ScreenShot::Ptr m_shot; bool finished = true; }; diff --git a/launcher/screenshots/Screenshot.h b/launcher/screenshots/Screenshot.h index 9db3a8a1..ca45aabf 100644 --- a/launcher/screenshots/Screenshot.h +++ b/launcher/screenshots/Screenshot.h @@ -5,10 +5,10 @@ #include <QFileInfo> #include <memory> -struct ScreenShot -{ - ScreenShot(QFileInfo file) - { +struct ScreenShot { + using Ptr = std::shared_ptr<ScreenShot>; + + ScreenShot(QFileInfo file) { m_file = file; } QFileInfo m_file; @@ -16,5 +16,3 @@ struct ScreenShot QString m_imgurId; QString m_imgurDeleteHash; }; - -typedef std::shared_ptr<ScreenShot> ScreenshotPtr; diff --git a/launcher/tasks/SequentialTask.cpp b/launcher/tasks/SequentialTask.cpp index d0777132..a66b9d78 100644 --- a/launcher/tasks/SequentialTask.cpp +++ b/launcher/tasks/SequentialTask.cpp @@ -4,7 +4,7 @@ SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(- { } -void SequentialTask::addTask(std::shared_ptr<Task> task) +void SequentialTask::addTask(Task::Ptr task) { m_queue.append(task); } @@ -19,7 +19,7 @@ void SequentialTask::startNext() { if (m_currentIndex != -1) { - std::shared_ptr<Task> previous = m_queue[m_currentIndex]; + Task::Ptr previous = m_queue[m_currentIndex]; disconnect(previous.get(), 0, this, 0); } m_currentIndex++; @@ -28,7 +28,7 @@ void SequentialTask::startNext() emitSucceeded(); return; } - std::shared_ptr<Task> next = m_queue[m_currentIndex]; + Task::Ptr next = m_queue[m_currentIndex]; connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString))); connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString))); connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64))); diff --git a/launcher/tasks/SequentialTask.h b/launcher/tasks/SequentialTask.h index 6898c8a6..027744f3 100644 --- a/launcher/tasks/SequentialTask.h +++ b/launcher/tasks/SequentialTask.h @@ -1,9 +1,9 @@ #pragma once #include "Task.h" +#include "QObjectPtr.h" #include <QQueue> -#include <memory> class SequentialTask : public Task { @@ -12,7 +12,7 @@ public: explicit SequentialTask(QObject *parent = 0); virtual ~SequentialTask() {}; - void addTask(std::shared_ptr<Task> task); + void addTask(Task::Ptr task); protected: void executeTask(); @@ -25,6 +25,6 @@ slots: void subTaskProgress(qint64 current, qint64 total); private: - QQueue<std::shared_ptr<Task> > m_queue; + QQueue<Task::Ptr > m_queue; int m_currentIndex; }; diff --git a/launcher/tasks/Task.h b/launcher/tasks/Task.h index 2367f1ec..9cf08dbd 100644 --- a/launcher/tasks/Task.h +++ b/launcher/tasks/Task.h @@ -19,10 +19,14 @@ #include <QString> #include <QStringList> +#include "QObjectPtr.h" + class Task : public QObject { Q_OBJECT public: + using Ptr = shared_qobject_ptr<Task>; + enum class State { Inactive, diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 29a952b0..ce53ac32 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -6,15 +6,17 @@ #include <QDir> #include <QLibraryInfo> #include <QDebug> -#include <FileSystem.h> -#include <net/NetJob.h> -#include <net/ChecksumValidator.h> -#include <Env.h> -#include <BuildConfig.h> + +#include "FileSystem.h" +#include "net/NetJob.h" +#include "net/ChecksumValidator.h" +#include "BuildConfig.h" #include "Json.h" #include "POTranslator.h" +#include "Application.h" + const static QLatin1Literal defaultLangCode("en_US"); enum class FileType @@ -119,10 +121,10 @@ struct TranslationsModel::Private std::unique_ptr<QTranslator> m_qt_translator; std::unique_ptr<QTranslator> m_app_translator; - std::shared_ptr<Net::Download> m_index_task; + Net::Download::Ptr m_index_task; QString m_downloadingTranslation; - NetJobPtr m_dl_job; - NetJobPtr m_index_job; + NetJob::Ptr m_dl_job; + NetJob::Ptr m_index_job; QString m_nextDownload; std::unique_ptr<POTranslator> m_po_translator; @@ -558,13 +560,13 @@ void TranslationsModel::downloadIndex() } qDebug() << "Downloading Translations Index..."; d->m_index_job.reset(new NetJob("Translations Index")); - MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "index_v2.json"); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("translations", "index_v2.json"); entry->setStale(true); d->m_index_task = Net::Download::makeCached(QUrl("https://files.multimc.org/translations/index_v2.json"), entry); d->m_index_job->addNetAction(d->m_index_task); connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed); connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexReceived); - d->m_index_job->start(); + d->m_index_job->start(APPLICATION->network()); } void TranslationsModel::updateLanguage(QString key) @@ -601,7 +603,7 @@ void TranslationsModel::downloadTranslation(QString key) } d->m_downloadingTranslation = key; - MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + key + ".qm"); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("translations", "mmc_" + key + ".qm"); entry->setStale(true); auto dl = Net::Download::makeCached(QUrl(BuildConfig.TRANSLATIONS_BASE_URL + lang->file_name), entry); @@ -615,7 +617,7 @@ void TranslationsModel::downloadTranslation(QString key) connect(d->m_dl_job.get(), &NetJob::succeeded, this, &TranslationsModel::dlGood); connect(d->m_dl_job.get(), &NetJob::failed, this, &TranslationsModel::dlFailed); - d->m_dl_job->start(); + d->m_dl_job->start(APPLICATION->network()); } void TranslationsModel::downloadNext() diff --git a/launcher/ColorCache.cpp b/launcher/ui/ColorCache.cpp index ef268dd2..ef268dd2 100644 --- a/launcher/ColorCache.cpp +++ b/launcher/ui/ColorCache.cpp diff --git a/launcher/ColorCache.h b/launcher/ui/ColorCache.h index a840664d..a840664d 100644 --- a/launcher/ColorCache.h +++ b/launcher/ui/ColorCache.h diff --git a/launcher/GuiUtil.cpp b/launcher/ui/GuiUtil.cpp index 3dd31c7a..efb1a4df 100644 --- a/launcher/GuiUtil.cpp +++ b/launcher/ui/GuiUtil.cpp @@ -4,11 +4,11 @@ #include <QApplication> #include <QFileDialog> -#include "dialogs/ProgressDialog.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/CustomMessageBox.h" #include "net/PasteUpload.h" -#include "dialogs/CustomMessageBox.h" -#include "Launcher.h" +#include "Application.h" #include <settings/SettingsObject.h> #include <DesktopServices.h> #include <BuildConfig.h> @@ -16,7 +16,7 @@ QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) { ProgressDialog dialog(parentWidget); - auto APIKeySetting = LAUNCHER->settings()->get("PasteEEAPIKey").toString(); + auto APIKeySetting = APPLICATION->settings()->get("PasteEEAPIKey").toString(); if(APIKeySetting == "multimc") { APIKeySetting = BuildConfig.PASTE_EE_KEY; @@ -35,8 +35,12 @@ QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) dialog.execWithTask(paste.get()); if (!paste->wasSuccessful()) { - CustomMessageBox::selectable(parentWidget, QObject::tr("Upload failed"), - paste->failReason(), QMessageBox::Critical)->exec(); + CustomMessageBox::selectable( + parentWidget, + QObject::tr("Upload failed"), + paste->failReason(), + QMessageBox::Critical + )->exec(); return QString(); } else @@ -66,8 +70,9 @@ static QStringList BrowseForFileInternal(QString context, QString caption, QStri { QString location = QStandardPaths::writableLocation(l); QFileInfo finfo(location); - if (!finfo.exists()) + if (!finfo.exists()) { return; + } locations.insert(location); }; f(QStandardPaths::DesktopLocation); diff --git a/launcher/GuiUtil.h b/launcher/ui/GuiUtil.h index 5e109383..5e109383 100644 --- a/launcher/GuiUtil.h +++ b/launcher/ui/GuiUtil.h diff --git a/launcher/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 8f73671b..ae765c3c 100644 --- a/launcher/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -14,7 +14,7 @@ */ #include "InstanceWindow.h" -#include "Launcher.h" +#include "Application.h" #include <QScrollBar> #include <QMessageBox> @@ -23,9 +23,10 @@ #include <qlayoutitem.h> #include <QCloseEvent> -#include <dialogs/CustomMessageBox.h> -#include <dialogs/ProgressDialog.h> -#include "widgets/PageContainer.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/widgets/PageContainer.h" + #include "InstancePageProvider.h" #include "icons/IconList.h" @@ -35,7 +36,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) { setAttribute(Qt::WA_DeleteOnClose); - auto icon = LAUNCHER->icons()->getIcon(m_instance->iconKey()); + auto icon = APPLICATION->icons()->getIcon(m_instance->iconKey()); QString windowTitle = tr("Console window for ") + m_instance->name(); // Set window properties @@ -87,9 +88,9 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) // restore window state { - auto base64State = LAUNCHER->settings()->get("ConsoleWindowState").toByteArray(); + auto base64State = APPLICATION->settings()->get("ConsoleWindowState").toByteArray(); restoreState(QByteArray::fromBase64(base64State)); - auto base64Geometry = LAUNCHER->settings()->get("ConsoleWindowGeometry").toByteArray(); + auto base64Geometry = APPLICATION->settings()->get("ConsoleWindowGeometry").toByteArray(); restoreGeometry(QByteArray::fromBase64(base64Geometry)); } @@ -148,7 +149,7 @@ void InstanceWindow::updateLaunchButtons() void InstanceWindow::on_btnLaunchMinecraftOffline_clicked() { - LAUNCHER->launch(m_instance, false, nullptr); + APPLICATION->launch(m_instance, false, nullptr); } void InstanceWindow::on_InstanceLaunchTask_changed(shared_qobject_ptr<LaunchTask> proc) @@ -183,8 +184,8 @@ void InstanceWindow::closeEvent(QCloseEvent *event) return; } - LAUNCHER->settings()->set("ConsoleWindowState", saveState().toBase64()); - LAUNCHER->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("ConsoleWindowState", saveState().toBase64()); + APPLICATION->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); emit isClosing(); event->accept(); } @@ -198,11 +199,11 @@ void InstanceWindow::on_btnKillMinecraft_clicked() { if(m_instance->isRunning()) { - LAUNCHER->kill(m_instance); + APPLICATION->kill(m_instance); } else { - LAUNCHER->launch(m_instance, true, nullptr); + APPLICATION->launch(m_instance, true, nullptr); } } diff --git a/launcher/InstanceWindow.h b/launcher/ui/InstanceWindow.h index cd7d2494..1acf684e 100644 --- a/launcher/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -16,11 +16,14 @@ #pragma once #include <QMainWindow> -#include "LaunchController.h" -#include <QObjectPtr.h> #include <QSystemTrayIcon> + +#include "LaunchController.h" #include "launch/LaunchTask.h" -#include "pages/BasePageContainer.h" + +#include "ui/pages/BasePageContainer.h" + +#include "QObjectPtr.h" class QPushButton; class PageContainer; diff --git a/launcher/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 21502894..95d9ae5d 100644 --- a/launcher/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include "MainWindow.h" @@ -47,7 +47,6 @@ #include <QtWidgets/QShortcut> #include <BaseInstance.h> -#include <Env.h> #include <InstanceList.h> #include <MMCZip.h> #include <icons/IconList.h> @@ -67,27 +66,31 @@ #include <DesktopServices.h> #include "InstanceWindow.h" #include "InstancePageProvider.h" -#include "instanceview/InstanceProxyModel.h" #include "JavaCommon.h" #include "LaunchController.h" -#include "instanceview/InstanceView.h" -#include "instanceview/InstanceDelegate.h" -#include "widgets/LabeledToolButton.h" -#include "dialogs/NewInstanceDialog.h" -#include "dialogs/ProgressDialog.h" -#include "dialogs/AboutDialog.h" -#include "dialogs/VersionSelectDialog.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/IconPickerDialog.h" -#include "dialogs/CopyInstanceDialog.h" -#include "dialogs/UpdateDialog.h" -#include "dialogs/EditAccountDialog.h" -#include "dialogs/NotificationDialog.h" -#include "dialogs/ExportInstanceDialog.h" -#include <InstanceImportTask.h> + +#include "ui/instanceview/InstanceProxyModel.h" +#include "ui/instanceview/InstanceView.h" +#include "ui/instanceview/InstanceDelegate.h" +#include "ui/widgets/LabeledToolButton.h" +#include "ui/dialogs/NewInstanceDialog.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/AboutDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/IconPickerDialog.h" +#include "ui/dialogs/CopyInstanceDialog.h" +#include "ui/dialogs/UpdateDialog.h" +#include "ui/dialogs/EditAccountDialog.h" +#include "ui/dialogs/NotificationDialog.h" +#include "ui/dialogs/ExportInstanceDialog.h" + #include "UpdateController.h" #include "KonamiCode.h" -#include <InstanceCopyTask.h> + +#include "InstanceImportTask.h" +#include "InstanceCopyTask.h" + #include "MMCTime.h" namespace { @@ -278,7 +281,7 @@ public: actionAddInstance = TranslatedAction(MainWindow); actionAddInstance->setObjectName(QStringLiteral("actionAddInstance")); - actionAddInstance->setIcon(LAUNCHER->getThemedIcon("new")); + actionAddInstance->setIcon(APPLICATION->getThemedIcon("new")); actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instance")); actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance.")); all_actions.append(&actionAddInstance); @@ -291,7 +294,7 @@ public: actionViewInstanceFolder = TranslatedAction(MainWindow); actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder")); - actionViewInstanceFolder->setIcon(LAUNCHER->getThemedIcon("viewfolder")); + actionViewInstanceFolder->setIcon(APPLICATION->getThemedIcon("viewfolder")); actionViewInstanceFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Instance Folder")); actionViewInstanceFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance folder in a file browser.")); all_actions.append(&actionViewInstanceFolder); @@ -299,7 +302,7 @@ public: actionViewCentralModsFolder = TranslatedAction(MainWindow); actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); - actionViewCentralModsFolder->setIcon(LAUNCHER->getThemedIcon("centralmods")); + actionViewCentralModsFolder->setIcon(APPLICATION->getThemedIcon("centralmods")); actionViewCentralModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Central Mods Folder")); actionViewCentralModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the central mods folder in a file browser.")); all_actions.append(&actionViewCentralModsFolder); @@ -311,7 +314,7 @@ public: foldersMenuButton->setMenu(foldersMenu); foldersMenuButton->setPopupMode(QToolButton::InstantPopup); foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - foldersMenuButton->setIcon(LAUNCHER->getThemedIcon("viewfolder")); + foldersMenuButton->setIcon(APPLICATION->getThemedIcon("viewfolder")); foldersMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&foldersMenuButton); QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow); @@ -320,7 +323,7 @@ public: actionSettings = TranslatedAction(MainWindow); actionSettings->setObjectName(QStringLiteral("actionSettings")); - actionSettings->setIcon(LAUNCHER->getThemedIcon("settings")); + actionSettings->setIcon(APPLICATION->getThemedIcon("settings")); actionSettings->setMenuRole(QAction::PreferencesRole); actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Settings")); actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings.")); @@ -333,7 +336,7 @@ public: if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { actionReportBug = TranslatedAction(MainWindow); actionReportBug->setObjectName(QStringLiteral("actionReportBug")); - actionReportBug->setIcon(LAUNCHER->getThemedIcon("bug")); + actionReportBug->setIcon(APPLICATION->getThemedIcon("bug")); actionReportBug.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Report a Bug")); actionReportBug.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the bug tracker to report a bug with %1.")); all_actions.append(&actionReportBug); @@ -343,7 +346,7 @@ public: if (!BuildConfig.DISCORD_URL.isEmpty()) { actionDISCORD = TranslatedAction(MainWindow); actionDISCORD->setObjectName(QStringLiteral("actionDISCORD")); - actionDISCORD->setIcon(LAUNCHER->getThemedIcon("discord")); + actionDISCORD->setIcon(APPLICATION->getThemedIcon("discord")); actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord")); actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 discord voice chat.")); all_actions.append(&actionDISCORD); @@ -353,7 +356,7 @@ public: if (!BuildConfig.SUBREDDIT_URL.isEmpty()) { actionREDDIT = TranslatedAction(MainWindow); actionREDDIT->setObjectName(QStringLiteral("actionREDDIT")); - actionREDDIT->setIcon(LAUNCHER->getThemedIcon("reddit-alien")); + actionREDDIT->setIcon(APPLICATION->getThemedIcon("reddit-alien")); actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Reddit")); actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open %1 subreddit.")); all_actions.append(&actionREDDIT); @@ -362,7 +365,7 @@ public: actionAbout = TranslatedAction(MainWindow); actionAbout->setObjectName(QStringLiteral("actionAbout")); - actionAbout->setIcon(LAUNCHER->getThemedIcon("about")); + actionAbout->setIcon(APPLICATION->getThemedIcon("about")); actionAbout->setMenuRole(QAction::AboutRole); actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "About %1")); actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about %1.")); @@ -375,7 +378,7 @@ public: helpMenuButton->setMenu(helpMenu); helpMenuButton->setPopupMode(QToolButton::InstantPopup); helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - helpMenuButton->setIcon(LAUNCHER->getThemedIcon("help")); + helpMenuButton->setIcon(APPLICATION->getThemedIcon("help")); helpMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&helpMenuButton); QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow); @@ -386,7 +389,7 @@ public: { actionCheckUpdate = TranslatedAction(MainWindow); actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); - actionCheckUpdate->setIcon(LAUNCHER->getThemedIcon("checkupdate")); + actionCheckUpdate->setIcon(APPLICATION->getThemedIcon("checkupdate")); actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Update")); actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for %1.")); all_actions.append(&actionCheckUpdate); @@ -397,7 +400,7 @@ public: actionPatreon = TranslatedAction(MainWindow); actionPatreon->setObjectName(QStringLiteral("actionPatreon")); - actionPatreon->setIcon(LAUNCHER->getThemedIcon("patreon")); + actionPatreon->setIcon(APPLICATION->getThemedIcon("patreon")); actionPatreon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Support %1")); actionPatreon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the %1 Patreon page.")); all_actions.append(&actionPatreon); @@ -406,7 +409,7 @@ public: actionCAT = TranslatedAction(MainWindow); actionCAT->setObjectName(QStringLiteral("actionCAT")); actionCAT->setCheckable(true); - actionCAT->setIcon(LAUNCHER->getThemedIcon("cat")); + actionCAT->setIcon(APPLICATION->getThemedIcon("cat")); actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Meow")); actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3")); actionCAT->setPriority(QAction::LowPriority); @@ -419,7 +422,7 @@ public: actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Accounts")); // FIXME: no tooltip! actionManageAccounts->setCheckable(false); - actionManageAccounts->setIcon(LAUNCHER->getThemedIcon("accounts")); + actionManageAccounts->setIcon(APPLICATION->getThemedIcon("accounts")); all_actions.append(&actionManageAccounts); all_toolbars.append(&mainToolBar); @@ -446,7 +449,7 @@ public: actionMoreNews = TranslatedAction(MainWindow); actionMoreNews->setObjectName(QStringLiteral("actionMoreNews")); - actionMoreNews->setIcon(LAUNCHER->getThemedIcon("news")); + actionMoreNews->setIcon(APPLICATION->getThemedIcon("news")); actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news...")); actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the development blog to read more news about %1.")); all_actions.append(&actionMoreNews); @@ -478,7 +481,7 @@ public: changeIconButton = new LabeledToolButton(MainWindow); changeIconButton->setObjectName(QStringLiteral("changeIconButton")); - changeIconButton->setIcon(LAUNCHER->getThemedIcon("news")); + changeIconButton->setIcon(APPLICATION->getThemedIcon("news")); changeIconButton->setToolTip(actionChangeInstIcon->toolTip()); changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); instanceToolBar->addWidget(changeIconButton); @@ -589,7 +592,7 @@ public: actionCopyInstance = TranslatedAction(MainWindow); actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance")); - actionCopyInstance->setIcon(LAUNCHER->getThemedIcon("copy")); + actionCopyInstance->setIcon(APPLICATION->getThemedIcon("copy")); actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Copy Instance")); actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance.")); all_actions.append(&actionCopyInstance); @@ -606,7 +609,7 @@ public: MainWindow->setObjectName(QStringLiteral("MainWindow")); } MainWindow->resize(800, 600); - MainWindow->setWindowIcon(LAUNCHER->getThemedIcon("logo")); + MainWindow->setWindowIcon(APPLICATION->getThemedIcon("logo")); MainWindow->setWindowTitle(BuildConfig.LAUNCHER_DISPLAYNAME); #ifndef QT_NO_ACCESSIBILITY MainWindow->setAccessibleName(BuildConfig.LAUNCHER_NAME); @@ -681,9 +684,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // Add the news label to the news toolbar. { - m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL)); + m_newsChecker.reset(new NewsChecker(APPLICATION->network(), BuildConfig.NEWS_RSS_URL)); newsLabel = new QToolButton(); - newsLabel->setIcon(LAUNCHER->getThemedIcon("news")); + newsLabel->setIcon(APPLICATION->getThemedIcon("news")); newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); newsLabel->setFocusPolicy(Qt::NoFocus); @@ -710,20 +713,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(view, &InstanceView::droppedURLs, this, &MainWindow::droppedURLs, Qt::QueuedConnection); proxymodel = new InstanceProxyModel(this); - proxymodel->setSourceModel(LAUNCHER->instances().get()); + proxymodel->setSourceModel(APPLICATION->instances().get()); proxymodel->sort(0); connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged); view->setModel(proxymodel); view->setSourceOfGroupCollapseStatus([](const QString & groupName)->bool { - return LAUNCHER->instances()->isGroupCollapsed(groupName); + return APPLICATION->instances()->isGroupCollapsed(groupName); }); - connect(view, &InstanceView::groupStateChanged, LAUNCHER->instances().get(), &InstanceList::on_GroupStateChanged); + connect(view, &InstanceView::groupStateChanged, APPLICATION->instances().get(), &InstanceList::on_GroupStateChanged); ui->horizontalLayout->addWidget(view); } // The cat background { - bool cat_enable = LAUNCHER->settings()->get("TheCat").toBool(); + bool cat_enable = APPLICATION->settings()->get("TheCat").toBool(); ui->actionCAT->setChecked(cat_enable); // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... connect(ui->actionCAT.operator->(), SIGNAL(toggled(bool)), SLOT(onCatToggled(bool))); @@ -736,16 +739,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(view->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::instanceChanged); // track icon changes and update the toolbar! - connect(LAUNCHER->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); + connect(APPLICATION->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); // model reset -> selection is invalid. All the instance pointers are wrong. - connect(LAUNCHER->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); + connect(APPLICATION->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); // handle newly added instances - connect(LAUNCHER->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); + connect(APPLICATION->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); // When the global settings page closes, we want to know about it and update our state - connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); + connect(APPLICATION, &Application::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); m_statusLeft = new QLabel(tr("No instance selected"), this); m_statusCenter = new QLabel(tr("Total playtime: 0s"), this); @@ -765,7 +768,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow accountMenuButton->setMenu(accountMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); QWidgetAction *accountMenuButtonAction = new QWidgetAction(this); accountMenuButtonAction->setDefaultWidget(accountMenuButton); @@ -776,14 +779,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit. // Template hell sucks... connect( - LAUNCHER->accounts().get(), - &AccountList::activeAccountChanged, + APPLICATION->accounts().get(), + &AccountList::defaultAccountChanged, [this] { - activeAccountChanged(); + defaultAccountChanged(); } ); connect( - LAUNCHER->accounts().get(), + APPLICATION->accounts().get(), &AccountList::listChanged, [this] { @@ -792,10 +795,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow ); // Show initial account - activeAccountChanged(); + defaultAccountChanged(); // TODO: refresh accounts here? - // auto accounts = LAUNCHER->accounts(); + // auto accounts = APPLICATION->accounts(); // load the news { @@ -806,20 +809,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow if(BuildConfig.UPDATER_ENABLED) { - bool updatesAllowed = LAUNCHER->updatesAreAllowed(); + bool updatesAllowed = APPLICATION->updatesAreAllowed(); updatesAllowedChanged(updatesAllowed); // NOTE: calling the operator like that is an ugly hack to appease ancient gcc... connect(ui->actionCheckUpdate.operator->(), &QAction::triggered, this, &MainWindow::checkForUpdates); // set up the updater object. - auto updater = LAUNCHER->updateChecker(); + auto updater = APPLICATION->updateChecker(); connect(updater.get(), &UpdateChecker::updateAvailable, this, &MainWindow::updateAvailable); connect(updater.get(), &UpdateChecker::noUpdateFound, this, &MainWindow::updateNotAvailable); // if automatic update checks are allowed, start one. - if (LAUNCHER->settings()->get("AutoUpdate").toBool() && updatesAllowed) + if (APPLICATION->settings()->get("AutoUpdate").toBool() && updatesAllowed) { - updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), false); + updater->checkForUpdate(APPLICATION->settings()->get("UpdateChannel").toString(), false); } } @@ -834,7 +837,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow checker->checkForNotifications(); } - setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); // removing this looks stupid view->setFocus(); @@ -844,10 +847,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow void MainWindow::retranslateUi() { - std::shared_ptr<AccountList> accounts = LAUNCHER->accounts(); - MinecraftAccountPtr active_account = accounts->activeAccount(); - if(active_account) { - auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse()); + auto accounts = APPLICATION->accounts(); + MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); + if(defaultAccount) { + auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); accountMenuButton->setText(profileLabel); } else { @@ -876,7 +879,6 @@ QMenu * MainWindow::createPopupMenu() void MainWindow::konamiTriggered() { - // ENV.enableFeature("NewModsPage"); qDebug() << "Super Secret Mode ACTIVATED!"; } @@ -982,16 +984,16 @@ void MainWindow::updateToolsMenu() QAction *normalLaunchOffline = launchOfflineMenu->addAction(tr("Launch Offline")); connect(normalLaunch, &QAction::triggered, [this]() { - LAUNCHER->launch(m_selectedInstance, true); + APPLICATION->launch(m_selectedInstance, true); }); connect(normalLaunchOffline, &QAction::triggered, [this]() { - LAUNCHER->launch(m_selectedInstance, false); + APPLICATION->launch(m_selectedInstance, false); }); QString profilersTitle = tr("Profilers"); launchMenu->addSeparator()->setText(profilersTitle); launchOfflineMenu->addSeparator()->setText(profilersTitle); - for (auto profiler : LAUNCHER->profilers().values()) + for (auto profiler : APPLICATION->profilers().values()) { QAction *profilerAction = launchMenu->addAction(profiler->name()); QAction *profilerOfflineAction = launchOfflineMenu->addAction(profiler->name()); @@ -1008,11 +1010,11 @@ void MainWindow::updateToolsMenu() { connect(profilerAction, &QAction::triggered, [this, profiler]() { - LAUNCHER->launch(m_selectedInstance, true, profiler.get()); + APPLICATION->launch(m_selectedInstance, true, profiler.get()); }); connect(profilerOfflineAction, &QAction::triggered, [this, profiler]() { - LAUNCHER->launch(m_selectedInstance, false, profiler.get()); + APPLICATION->launch(m_selectedInstance, false, profiler.get()); }); } } @@ -1024,17 +1026,16 @@ void MainWindow::repopulateAccountsMenu() { accountMenu->clear(); - std::shared_ptr<AccountList> accounts = LAUNCHER->accounts(); - MinecraftAccountPtr active_account = accounts->activeAccount(); + auto accounts = APPLICATION->accounts(); + MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); QString active_profileId = ""; - if (active_account != nullptr) + if (defaultAccount) { - active_profileId = active_account->profileId(); // this can be called before accountMenuButton exists if (accountMenuButton) { - auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse()); + auto profileLabel = profileInUseFilter(defaultAccount->profileName(), defaultAccount->isInUse()); accountMenuButton->setText(profileLabel); } } @@ -1053,14 +1054,20 @@ void MainWindow::repopulateAccountsMenu() MinecraftAccountPtr account = accounts->at(i); auto profileLabel = profileInUseFilter(account->profileName(), account->isInUse()); QAction *action = new QAction(profileLabel, this); - action->setData(account->profileId()); + action->setData(i); action->setCheckable(true); - if (active_profileId == account->profileId()) + if (defaultAccount == account) { action->setChecked(true); } - action->setIcon(account->getFace()); + auto face = account->getFace(); + if(!face.isNull()) { + action->setIcon(face); + } + else { + action->setIcon(APPLICATION->getThemedIcon("noaccount")); + } accountMenu->addAction(action); connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount())); } @@ -1070,9 +1077,9 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(tr("No Default Account"), this); action->setCheckable(true); - action->setIcon(LAUNCHER->getThemedIcon("noaccount")); - action->setData(""); - if (active_profileId.isEmpty()) { + action->setIcon(APPLICATION->getThemedIcon("noaccount")); + action->setData(-1); + if (!defaultAccount) { action->setChecked(true); } @@ -1098,40 +1105,45 @@ void MainWindow::updatesAllowedChanged(bool allowed) void MainWindow::changeActiveAccount() { QAction *sAction = (QAction *)sender(); + // Profile's associated Mojang username - // Will need to change when profiles are properly implemented - if (sAction->data().type() != QVariant::Type::String) + if (sAction->data().type() != QVariant::Type::Int) return; QVariant data = sAction->data(); - QString id = ""; - if (!data.isNull()) - { - id = data.toString(); + bool valid = false; + int index = data.toInt(&valid); + if(!valid) { + index = -1; } - - LAUNCHER->accounts()->setActiveAccount(id); - - activeAccountChanged(); + auto accounts = APPLICATION->accounts(); + accounts->setDefaultAccount(index == -1 ? nullptr : accounts->at(index)); + defaultAccountChanged(); } -void MainWindow::activeAccountChanged() +void MainWindow::defaultAccountChanged() { repopulateAccountsMenu(); - MinecraftAccountPtr account = LAUNCHER->accounts()->activeAccount(); + MinecraftAccountPtr account = APPLICATION->accounts()->defaultAccount(); // FIXME: this needs adjustment for MSA - if (account != nullptr && account->profileName() != "") + if (account && account->profileName() != "") { auto profileLabel = profileInUseFilter(account->profileName(), account->isInUse()); accountMenuButton->setText(profileLabel); - accountMenuButton->setIcon(account->getFace()); + auto face = account->getFace(); + if(face.isNull()) { + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); + } + else { + accountMenuButton->setIcon(face); + } return; } // Set the icon to the "no account" icon. - accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); + accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); accountMenuButton->setText(tr("Profiles")); } @@ -1193,7 +1205,7 @@ void MainWindow::updateNewsLabel() void MainWindow::updateAvailable(GoUpdate::Status status) { - if(!LAUNCHER->updatesAreAllowed()) + if(!APPLICATION->updatesAreAllowed()) { updateNotAvailable(); return; @@ -1239,7 +1251,7 @@ QString intListToString(const QList<int> &list) void MainWindow::notificationsChanged() { QList<NotificationChecker::NotificationEntry> entries = m_notificationChecker->notificationEntries(); - QList<int> shownNotifications = stringToIntList(LAUNCHER->settings()->get("ShownNotifications").toString()); + QList<int> shownNotifications = stringToIntList(APPLICATION->settings()->get("ShownNotifications").toString()); for (auto it = entries.begin(); it != entries.end(); ++it) { NotificationChecker::NotificationEntry entry = *it; @@ -1252,25 +1264,25 @@ void MainWindow::notificationsChanged() } } } - LAUNCHER->settings()->set("ShownNotifications", intListToString(shownNotifications)); + APPLICATION->settings()->set("ShownNotifications", intListToString(shownNotifications)); } void MainWindow::downloadUpdates(GoUpdate::Status status) { - if(!LAUNCHER->updatesAreAllowed()) + if(!APPLICATION->updatesAreAllowed()) { return; } qDebug() << "Downloading updates."; ProgressDialog updateDlg(this); - status.rootPath = LAUNCHER->root(); + status.rootPath = APPLICATION->root(); - auto dlPath = FS::PathCombine(LAUNCHER->root(), "update", "XXXXXX"); + auto dlPath = FS::PathCombine(APPLICATION->root(), "update", "XXXXXX"); if (!FS::ensureFilePathExists(dlPath)) { CustomMessageBox::selectable(this, tr("Error"), tr("Couldn't create folder for update downloads:\n%1").arg(dlPath), QMessageBox::Warning)->show(); } - GoUpdate::DownloadTask updateTask(status, dlPath, &updateDlg); + GoUpdate::DownloadTask updateTask(APPLICATION->network(), status, dlPath, &updateDlg); // If the task succeeds, install the updates. if (updateDlg.execWithTask(&updateTask)) { @@ -1278,10 +1290,10 @@ void MainWindow::downloadUpdates(GoUpdate::Status status) * NOTE: This disables launching instances until the update either succeeds (and this process exits) * or the update fails (and the control leaves this scope). */ - LAUNCHER->updateIsRunning(true); - UpdateController update(this, LAUNCHER->root(), updateTask.updateFilesDir(), updateTask.operations()); + APPLICATION->updateIsRunning(true); + UpdateController update(this, APPLICATION->root(), updateTask.updateFilesDir(), updateTask.operations()); update.installUpdates(); - LAUNCHER->updateIsRunning(false); + APPLICATION->updateIsRunning(false); } else { @@ -1292,7 +1304,7 @@ void MainWindow::downloadUpdates(GoUpdate::Status status) void MainWindow::onCatToggled(bool state) { setCatBackground(state); - LAUNCHER->settings()->set("TheCat", state); + APPLICATION->settings()->set("TheCat", state); } namespace { @@ -1350,7 +1362,7 @@ void MainWindow::runModalTask(Task *task) void MainWindow::instanceFromInstanceTask(InstanceTask *rawTask) { - unique_qobject_ptr<Task> task(LAUNCHER->instances()->wrapInstanceTask(rawTask)); + unique_qobject_ptr<Task> task(APPLICATION->instances()->wrapInstanceTask(rawTask)); runModalTask(task.get()); } @@ -1367,7 +1379,7 @@ void MainWindow::on_actionCopyInstance_triggered() copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); - unique_qobject_ptr<Task> task(LAUNCHER->instances()->wrapInstanceTask(copyTask)); + unique_qobject_ptr<Task> task(APPLICATION->instances()->wrapInstanceTask(copyTask)); runModalTask(task.get()); } @@ -1375,7 +1387,7 @@ void MainWindow::finalizeInstance(InstancePtr inst) { view->updateGeometries(); setSelectedInstanceById(inst->id()); - if (LAUNCHER->accounts()->anyAccountIsValid()) + if (APPLICATION->accounts()->anyAccountIsValid()) { ProgressDialog loadDialog(this); auto update = inst->createUpdateTask(Net::Mode::Online); @@ -1421,14 +1433,14 @@ void MainWindow::addInstance(QString url) if(groupName.isEmpty()) { - groupName = LAUNCHER->settings()->get("LastUsedGroupForNewInstance").toString(); + groupName = APPLICATION->settings()->get("LastUsedGroupForNewInstance").toString(); } NewInstanceDialog newInstDlg(groupName, url, this); if (!newInstDlg.exec()) return; - LAUNCHER->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); + APPLICATION->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); InstanceTask * creationTask = newInstDlg.extractTask(); if(creationTask) @@ -1479,7 +1491,7 @@ void MainWindow::on_actionChangeInstIcon_triggered() if (dlg.result() == QDialog::Accepted) { m_selectedInstance->setIconKey(dlg.selectedIconKey); - auto icon = LAUNCHER->icons()->getIcon(dlg.selectedIconKey); + auto icon = APPLICATION->icons()->getIcon(dlg.selectedIconKey); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1489,7 +1501,7 @@ void MainWindow::iconUpdated(QString icon) { if (icon == m_currentInstIcon) { - auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); + auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1498,7 +1510,7 @@ void MainWindow::iconUpdated(QString icon) void MainWindow::updateInstanceToolIcon(QString new_icon) { m_currentInstIcon = new_icon; - auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); + auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1507,7 +1519,7 @@ void MainWindow::setSelectedInstanceById(const QString &id) { if (id.isNull()) return; - const QModelIndex index = LAUNCHER->instances()->getInstanceIndexById(id); + const QModelIndex index = APPLICATION->instances()->getInstanceIndexById(id); if (index.isValid()) { QModelIndex selectionIndex = proxymodel->mapFromSource(index); @@ -1523,8 +1535,8 @@ void MainWindow::on_actionChangeInstGroup_triggered() bool ok = false; InstanceId instId = m_selectedInstance->id(); - QString name(LAUNCHER->instances()->getInstanceGroup(instId)); - auto groups = LAUNCHER->instances()->getGroups(); + QString name(APPLICATION->instances()->getInstanceGroup(instId)); + auto groups = APPLICATION->instances()->getGroups(); groups.insert(0, ""); groups.sort(Qt::CaseInsensitive); int foo = groups.indexOf(name); @@ -1533,7 +1545,7 @@ void MainWindow::on_actionChangeInstGroup_triggered() name = name.simplified(); if (ok) { - LAUNCHER->instances()->setInstanceGroup(instId, name); + APPLICATION->instances()->setInstanceGroup(instId, name); } } @@ -1555,25 +1567,25 @@ void MainWindow::deleteGroup() .arg(groupName), QMessageBox::Yes | QMessageBox::No); if(reply == QMessageBox::Yes) { - LAUNCHER->instances()->deleteGroup(groupName); + APPLICATION->instances()->deleteGroup(groupName); } } } void MainWindow::on_actionViewInstanceFolder_triggered() { - QString str = LAUNCHER->settings()->get("InstanceDir").toString(); + QString str = APPLICATION->settings()->get("InstanceDir").toString(); DesktopServices::openDirectory(str); } void MainWindow::refreshInstances() { - LAUNCHER->instances()->loadList(); + APPLICATION->instances()->loadList(); } void MainWindow::on_actionViewCentralModsFolder_triggered() { - DesktopServices::openDirectory(LAUNCHER->settings()->get("CentralModsDir").toString(), true); + DesktopServices::openDirectory(APPLICATION->settings()->get("CentralModsDir").toString(), true); } void MainWindow::on_actionConfig_Folder_triggered() @@ -1589,8 +1601,8 @@ void MainWindow::checkForUpdates() { if(BuildConfig.UPDATER_ENABLED) { - auto updater = LAUNCHER->updateChecker(); - updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), true); + auto updater = APPLICATION->updateChecker(); + updater->checkForUpdate(APPLICATION->settings()->get("UpdateChannel").toString(), true); } else { @@ -1600,13 +1612,13 @@ void MainWindow::checkForUpdates() void MainWindow::on_actionSettings_triggered() { - LAUNCHER->ShowGlobalSettings(this, "global-settings"); + APPLICATION->ShowGlobalSettings(this, "global-settings"); } void MainWindow::globalSettingsClosed() { // FIXME: quick HACK to make this work. improve, optimize. - LAUNCHER->instances()->loadList(); + APPLICATION->instances()->loadList(); proxymodel->invalidate(); proxymodel->sort(0); updateToolsMenu(); @@ -1616,32 +1628,32 @@ void MainWindow::globalSettingsClosed() void MainWindow::on_actionInstanceSettings_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "settings"); + APPLICATION->showInstanceWindow(m_selectedInstance, "settings"); } void MainWindow::on_actionEditInstNotes_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "notes"); + APPLICATION->showInstanceWindow(m_selectedInstance, "notes"); } void MainWindow::on_actionWorlds_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "worlds"); + APPLICATION->showInstanceWindow(m_selectedInstance, "worlds"); } void MainWindow::on_actionEditInstance_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance); + APPLICATION->showInstanceWindow(m_selectedInstance); } void MainWindow::on_actionScreenshots_triggered() { - LAUNCHER->showInstanceWindow(m_selectedInstance, "screenshots"); + APPLICATION->showInstanceWindow(m_selectedInstance, "screenshots"); } void MainWindow::on_actionManageAccounts_triggered() { - LAUNCHER->ShowGlobalSettings(this, "accounts"); + APPLICATION->ShowGlobalSettings(this, "accounts"); } void MainWindow::on_actionReportBug_triggered() @@ -1695,7 +1707,7 @@ void MainWindow::on_actionDeleteInstance_triggered() )->exec(); if (response == QMessageBox::Yes) { - LAUNCHER->instances()->deleteInstance(id); + APPLICATION->instances()->deleteInstance(id); } } @@ -1743,8 +1755,8 @@ void MainWindow::on_actionViewSelectedMCFolder_triggered() void MainWindow::closeEvent(QCloseEvent *event) { // Save the window state and geometry. - LAUNCHER->settings()->set("MainWindowState", saveState().toBase64()); - LAUNCHER->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("MainWindowState", saveState().toBase64()); + APPLICATION->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); event->accept(); emit isClosing(); } @@ -1763,7 +1775,7 @@ void MainWindow::instanceActivated(QModelIndex index) if (!index.isValid()) return; QString id = index.data(InstanceList::InstanceIDRole).toString(); - InstancePtr inst = LAUNCHER->instances()->getInstanceById(id); + InstancePtr inst = APPLICATION->instances()->getInstanceById(id); if (!inst) return; @@ -1778,24 +1790,24 @@ void MainWindow::on_actionLaunchInstance_triggered() } if(m_selectedInstance->isRunning()) { - LAUNCHER->kill(m_selectedInstance); + APPLICATION->kill(m_selectedInstance); } else { - LAUNCHER->launch(m_selectedInstance); + APPLICATION->launch(m_selectedInstance); } } void MainWindow::activateInstance(InstancePtr instance) { - LAUNCHER->launch(instance); + APPLICATION->launch(instance); } void MainWindow::on_actionLaunchInstanceOffline_triggered() { if (m_selectedInstance) { - LAUNCHER->launch(m_selectedInstance, false); + APPLICATION->launch(m_selectedInstance, false); } } @@ -1819,12 +1831,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & { if (!current.isValid()) { - LAUNCHER->settings()->set("SelectedInstance", QString()); + APPLICATION->settings()->set("SelectedInstance", QString()); selectionBad(); return; } QString id = current.data(InstanceList::InstanceIDRole).toString(); - m_selectedInstance = LAUNCHER->instances()->getInstanceById(id); + m_selectedInstance = APPLICATION->instances()->getInstanceById(id); if (m_selectedInstance) { ui->instanceToolBar->setEnabled(true); @@ -1847,12 +1859,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & updateToolsMenu(); - LAUNCHER->settings()->set("SelectedInstance", m_selectedInstance->id()); + APPLICATION->settings()->set("SelectedInstance", m_selectedInstance->id()); } else { ui->instanceToolBar->setEnabled(false); - LAUNCHER->settings()->set("SelectedInstance", QString()); + APPLICATION->settings()->set("SelectedInstance", QString()); selectionBad(); return; } @@ -1884,12 +1896,12 @@ void MainWindow::selectionBad() updateInstanceToolIcon("grass"); // ...and then see if we can enable the previously selected instance - setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); } void MainWindow::checkInstancePathForProblems() { - QString instanceFolder = LAUNCHER->settings()->get("InstanceDir").toString(); + QString instanceFolder = APPLICATION->settings()->get("InstanceDir").toString(); if (FS::checkProblemticPathJava(QDir(instanceFolder))) { QMessageBox warning(this); @@ -1928,9 +1940,9 @@ void MainWindow::checkInstancePathForProblems() void MainWindow::updateStatusCenter() { - m_statusCenter->setVisible(LAUNCHER->settings()->get("ShowGlobalGameTime").toBool()); + m_statusCenter->setVisible(APPLICATION->settings()->get("ShowGlobalGameTime").toBool()); - int timePlayed = LAUNCHER->instances()->getTotalPlayTime(); + int timePlayed = APPLICATION->instances()->getTotalPlayTime(); if (timePlayed > 0) { m_statusCenter->setText(tr("Total playtime: %1").arg(Time::prettifyDuration(timePlayed))); } diff --git a/launcher/MainWindow.h b/launcher/ui/MainWindow.h index c2ad46ea..7e1256cc 100644 --- a/launcher/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -166,7 +166,7 @@ private slots: void notificationsChanged(); - void activeAccountChanged(); + void defaultAccountChanged(); void changeActiveAccount(); diff --git a/launcher/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 0c3f07db..501156d0 100644 --- a/launcher/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -16,7 +16,7 @@ #include "AboutDialog.h" #include "ui_AboutDialog.h" #include <QIcon> -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" #include <net/NetJob.h> @@ -88,7 +88,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->urlLabel->setOpenExternalLinks(true); - ui->icon->setPixmap(LAUNCHER->getThemedIcon("logo").pixmap(64)); + ui->icon->setPixmap(APPLICATION->getThemedIcon("logo").pixmap(64)); ui->title->setText(launcherName); ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); @@ -133,10 +133,10 @@ AboutDialog::~AboutDialog() void AboutDialog::loadPatronList() { - netJob.reset(new NetJob("Patreon Patron List")); + netJob = new NetJob("Patreon Patron List"); netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://files.multimc.org/patrons.txt"), &dataSink)); connect(netJob.get(), &NetJob::succeeded, this, &AboutDialog::patronListLoaded); - netJob->start(); + netJob->start(APPLICATION->network()); } void AboutDialog::patronListLoaded() diff --git a/launcher/dialogs/AboutDialog.h b/launcher/ui/dialogs/AboutDialog.h index c7621c37..cc4b8850 100644 --- a/launcher/dialogs/AboutDialog.h +++ b/launcher/ui/dialogs/AboutDialog.h @@ -42,6 +42,6 @@ slots: private: Ui::AboutDialog *ui; - NetJobPtr netJob; + NetJob::Ptr netJob; QByteArray dataSink; }; diff --git a/launcher/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui index 422e877b..422e877b 100644 --- a/launcher/dialogs/AboutDialog.ui +++ b/launcher/ui/dialogs/AboutDialog.ui diff --git a/launcher/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 802016d9..e5113981 100644 --- a/launcher/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -16,11 +16,11 @@ #include <QLayout> #include <QPushButton> -#include "Launcher.h" +#include "Application.h" #include "CopyInstanceDialog.h" #include "ui_CopyInstanceDialog.h" -#include "dialogs/IconPickerDialog.h" +#include "ui/dialogs/IconPickerDialog.h" #include "BaseVersion.h" #include "icons/IconList.h" @@ -36,16 +36,16 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) layout()->setSizeConstraint(QLayout::SetFixedSize); InstIconKey = original->iconKey(); - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); ui->instNameTextBox->setText(original->name()); ui->instNameTextBox->setFocus(); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); groupList.removeOne(""); groupList.push_front(""); ui->groupBox->addItems(groupList); - int index = groupList.indexOf(LAUNCHER->instances()->getInstanceGroup(m_original->id())); + int index = groupList.indexOf(APPLICATION->instances()->getInstanceGroup(m_original->id())); if(index == -1) { index = 0; @@ -99,7 +99,7 @@ void CopyInstanceDialog::on_iconButton_clicked() if (dlg.result() == QDialog::Accepted) { InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); } } diff --git a/launcher/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index bf3cd920..bf3cd920 100644 --- a/launcher/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h diff --git a/launcher/dialogs/CopyInstanceDialog.ui b/launcher/ui/dialogs/CopyInstanceDialog.ui index f4b191e2..f4b191e2 100644 --- a/launcher/dialogs/CopyInstanceDialog.ui +++ b/launcher/ui/dialogs/CopyInstanceDialog.ui diff --git a/launcher/dialogs/CustomMessageBox.cpp b/launcher/ui/dialogs/CustomMessageBox.cpp index 19029f68..19029f68 100644 --- a/launcher/dialogs/CustomMessageBox.cpp +++ b/launcher/ui/dialogs/CustomMessageBox.cpp diff --git a/launcher/dialogs/CustomMessageBox.h b/launcher/ui/dialogs/CustomMessageBox.h index 712c6518..712c6518 100644 --- a/launcher/dialogs/CustomMessageBox.h +++ b/launcher/ui/dialogs/CustomMessageBox.h diff --git a/launcher/dialogs/EditAccountDialog.cpp b/launcher/ui/dialogs/EditAccountDialog.cpp index 002c064b..002c064b 100644 --- a/launcher/dialogs/EditAccountDialog.cpp +++ b/launcher/ui/dialogs/EditAccountDialog.cpp diff --git a/launcher/dialogs/EditAccountDialog.h b/launcher/ui/dialogs/EditAccountDialog.h index 6b5eb4aa..6b5eb4aa 100644 --- a/launcher/dialogs/EditAccountDialog.h +++ b/launcher/ui/dialogs/EditAccountDialog.h diff --git a/launcher/dialogs/EditAccountDialog.ui b/launcher/ui/dialogs/EditAccountDialog.ui index e87509bc..e87509bc 100644 --- a/launcher/dialogs/EditAccountDialog.ui +++ b/launcher/ui/dialogs/EditAccountDialog.ui diff --git a/launcher/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 639b7043..1a164875 100644 --- a/launcher/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -27,7 +27,7 @@ #include <QSaveFile> #include "MMCStrings.h" #include "SeparatorPrefixTree.h" -#include "Launcher.h" +#include "Application.h" #include <icons/IconList.h> #include <FileSystem.h> @@ -341,7 +341,7 @@ ExportInstanceDialog::~ExportInstanceDialog() void SaveIcon(InstancePtr m_instance) { auto iconKey = m_instance->iconKey(); - auto iconList = LAUNCHER->icons(); + auto iconList = APPLICATION->icons(); auto mmcIcon = iconList->icon(iconKey); if(!mmcIcon || mmcIcon->isBuiltIn()) { return; diff --git a/launcher/dialogs/ExportInstanceDialog.h b/launcher/ui/dialogs/ExportInstanceDialog.h index dea02d1b..dea02d1b 100644 --- a/launcher/dialogs/ExportInstanceDialog.h +++ b/launcher/ui/dialogs/ExportInstanceDialog.h diff --git a/launcher/dialogs/ExportInstanceDialog.ui b/launcher/ui/dialogs/ExportInstanceDialog.ui index bcd4e84a..bcd4e84a 100644 --- a/launcher/dialogs/ExportInstanceDialog.ui +++ b/launcher/ui/dialogs/ExportInstanceDialog.ui diff --git a/launcher/dialogs/IconPickerDialog.cpp b/launcher/ui/dialogs/IconPickerDialog.cpp index a1c432a8..fcb645db 100644 --- a/launcher/dialogs/IconPickerDialog.cpp +++ b/launcher/ui/dialogs/IconPickerDialog.cpp @@ -17,12 +17,12 @@ #include <QPushButton> #include <QFileDialog> -#include "Launcher.h" +#include "Application.h" #include "IconPickerDialog.h" #include "ui_IconPickerDialog.h" -#include "instanceview/InstanceDelegate.h" +#include "ui/instanceview/InstanceDelegate.h" #include "icons/IconList.h" #include "icons/IconUtils.h" @@ -59,7 +59,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) contentsWidget->installEventFilter(this); - contentsWidget->setModel(LAUNCHER->icons().get()); + contentsWidget->setModel(APPLICATION->icons().get()); // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win. auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole); @@ -106,12 +106,12 @@ void IconPickerDialog::addNewIcon() //: The type of icon files auto filter = IconUtils::getIconFilter(); QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), tr("Icons %1").arg(filter)); - LAUNCHER->icons()->installIcons(fileNames); + APPLICATION->icons()->installIcons(fileNames); } void IconPickerDialog::removeSelectedIcon() { - LAUNCHER->icons()->deleteIcon(selectedIconKey); + APPLICATION->icons()->deleteIcon(selectedIconKey); } void IconPickerDialog::activated(QModelIndex index) @@ -133,7 +133,7 @@ void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection int IconPickerDialog::execWithSelection(QString selection) { - auto list = LAUNCHER->icons(); + auto list = APPLICATION->icons(); auto contentsWidget = ui->iconView; selectedIconKey = selection; @@ -159,5 +159,5 @@ IconPickerDialog::~IconPickerDialog() void IconPickerDialog::openFolder() { - DesktopServices::openDirectory(LAUNCHER->icons()->getDirectory(), true); + DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true); } diff --git a/launcher/dialogs/IconPickerDialog.h b/launcher/ui/dialogs/IconPickerDialog.h index 9af6a678..9af6a678 100644 --- a/launcher/dialogs/IconPickerDialog.h +++ b/launcher/ui/dialogs/IconPickerDialog.h diff --git a/launcher/dialogs/IconPickerDialog.ui b/launcher/ui/dialogs/IconPickerDialog.ui index c548edfb..c548edfb 100644 --- a/launcher/dialogs/IconPickerDialog.ui +++ b/launcher/ui/dialogs/IconPickerDialog.ui diff --git a/launcher/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp index bf0806e1..bf0806e1 100644 --- a/launcher/dialogs/LoginDialog.cpp +++ b/launcher/ui/dialogs/LoginDialog.cpp diff --git a/launcher/dialogs/LoginDialog.h b/launcher/ui/dialogs/LoginDialog.h index 13463640..f8101ff5 100644 --- a/launcher/dialogs/LoginDialog.h +++ b/launcher/ui/dialogs/LoginDialog.h @@ -19,6 +19,7 @@ #include <QtCore/QEventLoop> #include "minecraft/auth/MinecraftAccount.h" +#include "tasks/Task.h" namespace Ui { @@ -54,5 +55,5 @@ slots: private: Ui::LoginDialog *ui; MinecraftAccountPtr m_account; - std::shared_ptr<Task> m_loginTask; + Task::Ptr m_loginTask; }; diff --git a/launcher/dialogs/LoginDialog.ui b/launcher/ui/dialogs/LoginDialog.ui index 8fa4a45d..8fa4a45d 100644 --- a/launcher/dialogs/LoginDialog.ui +++ b/launcher/ui/dialogs/LoginDialog.ui diff --git a/launcher/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index 15c04061..15c04061 100644 --- a/launcher/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp diff --git a/launcher/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h index 3d26a0dd..4cf146ab 100644 --- a/launcher/dialogs/MSALoginDialog.h +++ b/launcher/ui/dialogs/MSALoginDialog.h @@ -55,7 +55,7 @@ slots: private: Ui::MSALoginDialog *ui; MinecraftAccountPtr m_account; - std::shared_ptr<AccountTask> m_loginTask; + shared_qobject_ptr<AccountTask> m_loginTask; QTimer m_externalLoginTimer; int m_externalLoginElapsed = 0; int m_externalLoginTimeout = 0; diff --git a/launcher/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui index 78cbfb26..78cbfb26 100644 --- a/launcher/dialogs/MSALoginDialog.ui +++ b/launcher/ui/dialogs/MSALoginDialog.ui diff --git a/launcher/dialogs/NewComponentDialog.cpp b/launcher/ui/dialogs/NewComponentDialog.cpp index 1cea54f4..1bbafb0c 100644 --- a/launcher/dialogs/NewComponentDialog.cpp +++ b/launcher/ui/dialogs/NewComponentDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "NewComponentDialog.h" #include "ui_NewComponentDialog.h" @@ -46,7 +46,7 @@ NewComponentDialog::NewComponentDialog(const QString & initialName, const QStrin connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); ui->nameTextBox->setFocus(); originalPlaceholderText = ui->uidTextBox->placeholderText(); diff --git a/launcher/dialogs/NewComponentDialog.h b/launcher/ui/dialogs/NewComponentDialog.h index 8c790beb..8c790beb 100644 --- a/launcher/dialogs/NewComponentDialog.h +++ b/launcher/ui/dialogs/NewComponentDialog.h diff --git a/launcher/dialogs/NewComponentDialog.ui b/launcher/ui/dialogs/NewComponentDialog.ui index 03b0d222..03b0d222 100644 --- a/launcher/dialogs/NewComponentDialog.ui +++ b/launcher/ui/dialogs/NewComponentDialog.ui diff --git a/launcher/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index d18eb3d5..b402839c 100644 --- a/launcher/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include "NewInstanceDialog.h" #include "ui_NewInstanceDialog.h" @@ -32,14 +32,14 @@ #include <QValidator> #include <QDialogButtonBox> -#include "widgets/PageContainer.h" -#include <pages/modplatform/VanillaPage.h> -#include <pages/modplatform/atlauncher/AtlPage.h> -#include <pages/modplatform/ftb/FtbPage.h> -#include <pages/modplatform/legacy_ftb/Page.h> -#include <pages/modplatform/flame/FlamePage.h> -#include <pages/modplatform/ImportPage.h> -#include <pages/modplatform/technic/TechnicPage.h> +#include "ui/widgets/PageContainer.h" +#include "ui/pages/modplatform/VanillaPage.h" +#include "ui/pages/modplatform/atlauncher/AtlPage.h" +#include "ui/pages/modplatform/ftb/FtbPage.h" +#include "ui/pages/modplatform/legacy_ftb/Page.h" +#include "ui/pages/modplatform/flame/FlamePage.h" +#include "ui/pages/modplatform/ImportPage.h" +#include "ui/pages/modplatform/technic/TechnicPage.h" @@ -48,12 +48,12 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString { ui->setupUi(this); - setWindowIcon(LAUNCHER->getThemedIcon("new")); + setWindowIcon(APPLICATION->getThemedIcon("new")); InstIconKey = "default"; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - auto groups = LAUNCHER->instances()->getGroups().toSet(); + auto groups = APPLICATION->instances()->getGroups().toSet(); auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); groupList.removeOne(""); @@ -105,18 +105,18 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString updateDialogState(); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("NewInstanceGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("NewInstanceGeometry").toByteArray())); } void NewInstanceDialog::reject() { - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); QDialog::reject(); } void NewInstanceDialog::accept() { - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); importIconNow(); QDialog::accept(); } @@ -155,7 +155,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task if(!task) { - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon("default")); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default")); importIcon = false; } @@ -175,7 +175,7 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QStr void NewInstanceDialog::setSuggestedIcon(const QString &key) { - auto icon = LAUNCHER->icons()->getIcon(key); + auto icon = APPLICATION->icons()->getIcon(key); importIcon = false; ui->iconButton->setIcon(icon); @@ -234,7 +234,7 @@ void NewInstanceDialog::on_iconButton_clicked() if (dlg.result() == QDialog::Accepted) { InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); importIcon = false; } } @@ -247,9 +247,9 @@ void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) void NewInstanceDialog::importIconNow() { if(importIcon) { - LAUNCHER->icons()->installIcon(importIconPath, importIconName); + APPLICATION->icons()->installIcon(importIconPath, importIconName); InstIconKey = importIconName; importIcon = false; } - LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); } diff --git a/launcher/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index 53abf8cf..ef74634e 100644 --- a/launcher/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -18,7 +18,7 @@ #include <QDialog> #include "BaseVersion.h" -#include "pages/BasePageProvider.h" +#include "ui/pages/BasePageProvider.h" #include "InstanceTask.h" namespace Ui diff --git a/launcher/dialogs/NewInstanceDialog.ui b/launcher/ui/dialogs/NewInstanceDialog.ui index 7fb19ff5..7fb19ff5 100644 --- a/launcher/dialogs/NewInstanceDialog.ui +++ b/launcher/ui/dialogs/NewInstanceDialog.ui diff --git a/launcher/dialogs/NotificationDialog.cpp b/launcher/ui/dialogs/NotificationDialog.cpp index f2a35ae2..f2a35ae2 100644 --- a/launcher/dialogs/NotificationDialog.cpp +++ b/launcher/ui/dialogs/NotificationDialog.cpp diff --git a/launcher/dialogs/NotificationDialog.h b/launcher/ui/dialogs/NotificationDialog.h index e1cbb9fa..e1cbb9fa 100644 --- a/launcher/dialogs/NotificationDialog.h +++ b/launcher/ui/dialogs/NotificationDialog.h diff --git a/launcher/dialogs/NotificationDialog.ui b/launcher/ui/dialogs/NotificationDialog.ui index 3e6c22bc..3e6c22bc 100644 --- a/launcher/dialogs/NotificationDialog.ui +++ b/launcher/ui/dialogs/NotificationDialog.ui diff --git a/launcher/dialogs/ProfileSelectDialog.cpp b/launcher/ui/dialogs/ProfileSelectDialog.cpp index 1082748f..7882cf45 100644 --- a/launcher/dialogs/ProfileSelectDialog.cpp +++ b/launcher/ui/dialogs/ProfileSelectDialog.cpp @@ -14,23 +14,22 @@ */ #include "ProfileSelectDialog.h" -#include <SkinUtils.h> #include "ui_ProfileSelectDialog.h" #include <QItemSelectionModel> - #include <QDebug> -#include <dialogs/ProgressDialog.h> +#include "SkinUtils.h" +#include "Application.h" -#include <Launcher.h> +#include "ui/dialogs/ProgressDialog.h" ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent) : QDialog(parent), ui(new Ui::ProfileSelectDialog) { ui->setupUi(this); - m_accounts = LAUNCHER->accounts(); + m_accounts = APPLICATION->accounts(); auto view = ui->listView; //view->setModel(m_accounts.get()); //view->hideColumn(AccountList::ActiveColumn); diff --git a/launcher/dialogs/ProfileSelectDialog.h b/launcher/ui/dialogs/ProfileSelectDialog.h index a4acd9a1..38aa4249 100644 --- a/launcher/dialogs/ProfileSelectDialog.h +++ b/launcher/ui/dialogs/ProfileSelectDialog.h @@ -80,7 +80,7 @@ slots: void on_buttonBox_rejected(); protected: - std::shared_ptr<AccountList> m_accounts; + shared_qobject_ptr<AccountList> m_accounts; //! The account that was selected when the user clicked OK. MinecraftAccountPtr m_selected; diff --git a/launcher/dialogs/ProfileSelectDialog.ui b/launcher/ui/dialogs/ProfileSelectDialog.ui index e779b51b..e779b51b 100644 --- a/launcher/dialogs/ProfileSelectDialog.ui +++ b/launcher/ui/dialogs/ProfileSelectDialog.ui diff --git a/launcher/ui/dialogs/ProfileSetupDialog.cpp b/launcher/ui/dialogs/ProfileSetupDialog.cpp new file mode 100644 index 00000000..d3e2b9a4 --- /dev/null +++ b/launcher/ui/dialogs/ProfileSetupDialog.cpp @@ -0,0 +1,250 @@ +/* Copyright 2013-2021 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 "ProfileSetupDialog.h" +#include "ui_ProfileSetupDialog.h" + +#include <QPushButton> +#include <QAction> +#include <QRegExpValidator> +#include <QJsonDocument> +#include <QDebug> + +#include "ui/dialogs/ProgressDialog.h" + +#include <Application.h> +#include "minecraft/auth/flows/AuthRequest.h" +#include "minecraft/auth/flows/Parsers.h" + + +ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent) + : QDialog(parent), m_accountToSetup(accountToSetup), ui(new Ui::ProfileSetupDialog) +{ + ui->setupUi(this); + ui->errorLabel->setVisible(false); + + goodIcon = APPLICATION->getThemedIcon("status-good"); + yellowIcon = APPLICATION->getThemedIcon("status-yellow"); + badIcon = APPLICATION->getThemedIcon("status-bad"); + + QRegExp permittedNames("[a-zA-Z0-9_]{3,16}"); + auto nameEdit = ui->nameEdit; + nameEdit->setValidator(new QRegExpValidator(permittedNames)); + nameEdit->setClearButtonEnabled(true); + validityAction = nameEdit->addAction(yellowIcon, QLineEdit::LeadingPosition); + connect(nameEdit, &QLineEdit::textEdited, this, &ProfileSetupDialog::nameEdited); + + checkStartTimer.setSingleShot(true); + connect(&checkStartTimer, &QTimer::timeout, this, &ProfileSetupDialog::startCheck); + + setNameStatus(NameStatus::NotSet, QString()); +} + +ProfileSetupDialog::~ProfileSetupDialog() +{ + delete ui; +} + +void ProfileSetupDialog::on_buttonBox_accepted() +{ + setupProfile(currentCheck); +} + +void ProfileSetupDialog::on_buttonBox_rejected() +{ + reject(); +} + +void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QString errorString = QString()) +{ + nameStatus = status; + auto okButton = ui->buttonBox->button(QDialogButtonBox::Ok); + switch(nameStatus) + { + case NameStatus::Available: { + validityAction->setIcon(goodIcon); + okButton->setEnabled(true); + } + break; + case NameStatus::NotSet: + case NameStatus::Pending: + validityAction->setIcon(yellowIcon); + okButton->setEnabled(false); + break; + case NameStatus::Exists: + case NameStatus::Error: + validityAction->setIcon(badIcon); + okButton->setEnabled(false); + break; + } + if(!errorString.isEmpty()) { + ui->errorLabel->setText(errorString); + ui->errorLabel->setVisible(true); + } + else { + ui->errorLabel->setVisible(false); + } +} + +void ProfileSetupDialog::nameEdited(const QString& name) +{ + if(!ui->nameEdit->hasAcceptableInput()) { + setNameStatus(NameStatus::NotSet, tr("Name is too short - must be between 3 and 16 characters long.")); + return; + } + scheduleCheck(name); +} + +void ProfileSetupDialog::scheduleCheck(const QString& name) { + queuedCheck = name; + setNameStatus(NameStatus::Pending); + checkStartTimer.start(1000); +} + +void ProfileSetupDialog::startCheck() { + if(isChecking) { + return; + } + if(queuedCheck.isNull()) { + return; + } + checkName(queuedCheck); +} + + +void ProfileSetupDialog::checkName(const QString &name) { + if(isChecking) { + return; + } + + currentCheck = name; + isChecking = true; + + auto token = m_accountToSetup->accessToken(); + + auto url = QString("https://api.minecraftservices.com/minecraft/profile/name/%1/available").arg(name); + QNetworkRequest request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8()); + + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::checkFinished); + requestor->get(request); +} + +void ProfileSetupDialog::checkFinished( + QNetworkReply::NetworkError error, + QByteArray data, + QList<QNetworkReply::RawHeaderPair> headers +) { + if(error == QNetworkReply::NoError) { + auto doc = QJsonDocument::fromJson(data); + auto root = doc.object(); + auto statusValue = root.value("status").toString("INVALID"); + if(statusValue == "AVAILABLE") { + setNameStatus(NameStatus::Available); + } + else if (statusValue == "DUPLICATE") { + setNameStatus(NameStatus::Exists, tr("Minecraft profile with name %1 already exists.").arg(currentCheck)); + } + else if (statusValue == "NOT_ALLOWED") { + setNameStatus(NameStatus::Exists, tr("The name %1 is not allowed.").arg(currentCheck)); + } + else { + setNameStatus(NameStatus::Error, tr("Unhandled profile name status: %1").arg(statusValue)); + } + } + else { + setNameStatus(NameStatus::Error, tr("Failed to check name availability.")); + } + isChecking = false; +} + +void ProfileSetupDialog::setupProfile(const QString &profileName) { + if(isWorking) { + return; + } + + auto token = m_accountToSetup->accessToken(); + + auto url = QString("https://api.minecraftservices.com/minecraft/profile"); + QNetworkRequest request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8()); + + QString payloadTemplate("{\"profileName\":\"%1\"}"); + auto data = payloadTemplate.arg(profileName).toUtf8(); + + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::setupProfileFinished); + requestor->post(request, data); + isWorking = true; + + auto button = ui->buttonBox->button(QDialogButtonBox::Cancel); + button->setEnabled(false); +} + +namespace { + +struct MojangError{ + static MojangError fromJSON(QByteArray data) { + MojangError out; + out.error = QString::fromUtf8(data); + auto doc = QJsonDocument::fromJson(data, &out.parseError); + auto object = doc.object(); + + out.fullyParsed = true; + out.fullyParsed &= Parsers::getString(object.value("path"), out.path); + out.fullyParsed &= Parsers::getString(object.value("error"), out.error); + out.fullyParsed &= Parsers::getString(object.value("errorMessage"), out.errorMessage); + + return out; + } + + QString rawError; + QJsonParseError parseError; + bool fullyParsed; + + QString path; + QString error; + QString errorMessage; +}; + +} + +void ProfileSetupDialog::setupProfileFinished( + QNetworkReply::NetworkError error, + QByteArray data, + QList<QNetworkReply::RawHeaderPair> headers +) { + isWorking = false; + if(error == QNetworkReply::NoError) { + /* + * data contains the profile in the response + * ... we could parse it and update the account, but let's just return back to the normal login flow instead... + */ + accept(); + } + else { + auto parsedError = MojangError::fromJSON(data); + ui->errorLabel->setVisible(true); + ui->errorLabel->setText(tr("The server returned the following error:") + "\n\n" + parsedError.errorMessage); + qDebug() << parsedError.rawError; + auto button = ui->buttonBox->button(QDialogButtonBox::Cancel); + button->setEnabled(true); + } +} diff --git a/launcher/ui/dialogs/ProfileSetupDialog.h b/launcher/ui/dialogs/ProfileSetupDialog.h new file mode 100644 index 00000000..6f413ebd --- /dev/null +++ b/launcher/ui/dialogs/ProfileSetupDialog.h @@ -0,0 +1,88 @@ +/* Copyright 2013-2021 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 <QDialog> +#include <QIcon> +#include <QTimer> +#include <QNetworkReply> + +#include <memory> +#include <minecraft/auth/MinecraftAccount.h> + +namespace Ui +{ +class ProfileSetupDialog; +} + +class ProfileSetupDialog : public QDialog +{ + Q_OBJECT +public: + + explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent = 0); + ~ProfileSetupDialog(); + + enum class NameStatus + { + NotSet, + Pending, + Available, + Exists, + Error + } nameStatus = NameStatus::NotSet; + +private slots: + void on_buttonBox_accepted(); + void on_buttonBox_rejected(); + + void nameEdited(const QString &name); + void checkFinished( + QNetworkReply::NetworkError error, + QByteArray data, + QList<QNetworkReply::RawHeaderPair> headers + ); + void startCheck(); + + void setupProfileFinished( + QNetworkReply::NetworkError error, + QByteArray data, + QList<QNetworkReply::RawHeaderPair> headers + ); +protected: + void scheduleCheck(const QString &name); + void checkName(const QString &name); + void setNameStatus(NameStatus status, QString errorString); + + void setupProfile(const QString & profileName); + +private: + MinecraftAccountPtr m_accountToSetup; + Ui::ProfileSetupDialog *ui; + QIcon goodIcon; + QIcon yellowIcon; + QIcon badIcon; + QAction * validityAction = nullptr; + + QString queuedCheck; + + bool isChecking = false; + bool isWorking = false; + QString currentCheck; + + QTimer checkStartTimer; +}; + diff --git a/launcher/ui/dialogs/ProfileSetupDialog.ui b/launcher/ui/dialogs/ProfileSetupDialog.ui new file mode 100644 index 00000000..9dbabb4b --- /dev/null +++ b/launcher/ui/dialogs/ProfileSetupDialog.ui @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ProfileSetupDialog</class> + <widget class="QDialog" name="ProfileSetupDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>615</width> + <height>208</height> + </rect> + </property> + <property name="windowTitle"> + <string>Choose Minecraft name</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="descriptionLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>You just need to take one more step to be able to play Minecraft on this account. + +Choose your name carefully:</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="buddy"> + <cstring>nameEdit</cstring> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLineEdit" name="nameEdit"/> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="errorLabel"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string notr="true">Errors go here</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>nameEdit</tabstop> + </tabstops> + <resources/> + <connections/> +</ui> diff --git a/launcher/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 4b092859..4b092859 100644 --- a/launcher/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp diff --git a/launcher/dialogs/ProgressDialog.h b/launcher/ui/dialogs/ProgressDialog.h index b28ad4fa..b28ad4fa 100644 --- a/launcher/dialogs/ProgressDialog.h +++ b/launcher/ui/dialogs/ProgressDialog.h diff --git a/launcher/dialogs/ProgressDialog.ui b/launcher/ui/dialogs/ProgressDialog.ui index 04b8fef3..04b8fef3 100644 --- a/launcher/dialogs/ProgressDialog.ui +++ b/launcher/ui/dialogs/ProgressDialog.ui diff --git a/launcher/dialogs/SkinUploadDialog.cpp b/launcher/ui/dialogs/SkinUploadDialog.cpp index 97478f4b..4e6142fa 100644 --- a/launcher/dialogs/SkinUploadDialog.cpp +++ b/launcher/ui/dialogs/SkinUploadDialog.cpp @@ -3,14 +3,15 @@ #include <QPainter> #include <FileSystem.h> + #include <minecraft/services/SkinUpload.h> +#include <minecraft/services/CapeChange.h> #include <tasks/SequentialTask.h> #include "SkinUploadDialog.h" #include "ui_SkinUploadDialog.h" #include "ProgressDialog.h" #include "CustomMessageBox.h" -#include <minecraft/services/CapeChange.h> void SkinUploadDialog::on_buttonBox_rejected() { @@ -91,10 +92,10 @@ void SkinUploadDialog::on_buttonBox_accepted() model = SkinUpload::ALEX; } SequentialTask skinUpload; - skinUpload.addTask(std::make_shared<SkinUpload>(this, session, FS::read(fileName), model)); + skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, session, FS::read(fileName), model))); auto selectedCape = ui->capeCombo->currentData().toString(); - if(selectedCape != session->m_accountPtr->accountData()->minecraftProfile.currentCape) { - skinUpload.addTask(std::make_shared<CapeChange>(this, session, selectedCape)); + if(selectedCape != m_acct->accountData()->minecraftProfile.currentCape) { + skinUpload.addTask(shared_qobject_ptr<CapeChange>(new CapeChange(this, session, selectedCape))); } if (prog.execWithTask(&skinUpload) != QDialog::Accepted) { diff --git a/launcher/dialogs/SkinUploadDialog.h b/launcher/ui/dialogs/SkinUploadDialog.h index 84d17dc6..84d17dc6 100644 --- a/launcher/dialogs/SkinUploadDialog.h +++ b/launcher/ui/dialogs/SkinUploadDialog.h diff --git a/launcher/dialogs/SkinUploadDialog.ui b/launcher/ui/dialogs/SkinUploadDialog.ui index f4b0ed0a..f4b0ed0a 100644 --- a/launcher/dialogs/SkinUploadDialog.ui +++ b/launcher/ui/dialogs/SkinUploadDialog.ui diff --git a/launcher/dialogs/UpdateDialog.cpp b/launcher/ui/dialogs/UpdateDialog.cpp index ca3bd915..4a6a1fdd 100644 --- a/launcher/dialogs/UpdateDialog.cpp +++ b/launcher/ui/dialogs/UpdateDialog.cpp @@ -1,7 +1,7 @@ #include "UpdateDialog.h" #include "ui_UpdateDialog.h" #include <QDebug> -#include "Launcher.h" +#include "Application.h" #include <settings/SettingsObject.h> #include <Json.h> @@ -11,7 +11,7 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) { ui->setupUi(this); - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); if(hasUpdate) { ui->label->setText(tr("A new %1 update is available!").arg(channel)); @@ -24,7 +24,7 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), u } ui->changelogBrowser->setHtml(tr("<center><h1>Loading changelog...</h1></center>")); loadChangelog(); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("UpdateDialogGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("UpdateDialogGeometry").toByteArray())); } UpdateDialog::~UpdateDialog() @@ -33,7 +33,7 @@ UpdateDialog::~UpdateDialog() void UpdateDialog::loadChangelog() { - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); dljob.reset(new NetJob("Changelog")); QString url; if(channel == "stable") @@ -49,7 +49,7 @@ void UpdateDialog::loadChangelog() dljob->addNetAction(Net::Download::makeByteArray(QUrl(url), &changelogData)); connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded); connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed); - dljob->start(); + dljob->start(APPLICATION->network()); } QString reprocessMarkdown(QByteArray markdown) @@ -65,7 +65,7 @@ QString reprocessMarkdown(QByteArray markdown) QString reprocessCommits(QByteArray json) { - auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); + auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); try { QString result; @@ -177,6 +177,6 @@ void UpdateDialog::on_btnUpdateNow_clicked() void UpdateDialog::closeEvent(QCloseEvent* evt) { - LAUNCHER->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); QDialog::closeEvent(evt); } diff --git a/launcher/dialogs/UpdateDialog.h b/launcher/ui/dialogs/UpdateDialog.h index ae1799c3..07cbe09f 100644 --- a/launcher/dialogs/UpdateDialog.h +++ b/launcher/ui/dialogs/UpdateDialog.h @@ -62,6 +62,6 @@ protected: private: Ui::UpdateDialog *ui; QByteArray changelogData; - NetJobPtr dljob; + NetJob::Ptr dljob; ChangelogType m_changelogType = CHANGELOG_MARKDOWN; }; diff --git a/launcher/dialogs/UpdateDialog.ui b/launcher/ui/dialogs/UpdateDialog.ui index b0b3dd83..b0b3dd83 100644 --- a/launcher/dialogs/UpdateDialog.ui +++ b/launcher/ui/dialogs/UpdateDialog.ui diff --git a/launcher/dialogs/VersionSelectDialog.cpp b/launcher/ui/dialogs/VersionSelectDialog.cpp index 82eb70f4..70ef72d6 100644 --- a/launcher/dialogs/VersionSelectDialog.cpp +++ b/launcher/ui/dialogs/VersionSelectDialog.cpp @@ -20,17 +20,17 @@ #include <QtWidgets/QHBoxLayout> #include <QtWidgets/QPushButton> #include <QtWidgets/QVBoxLayout> +#include <QDebug> -#include <dialogs/ProgressDialog.h> -#include "CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/widgets/VersionSelectWidget.h" +#include "ui/dialogs/CustomMessageBox.h" -#include <BaseVersion.h> -#include <BaseVersionList.h> -#include <tasks/Task.h> -#include <QDebug> -#include "Launcher.h" -#include <VersionProxyModel.h> -#include <widgets/VersionSelectWidget.h> +#include "BaseVersion.h" +#include "BaseVersionList.h" +#include "tasks/Task.h" +#include "Application.h" +#include "VersionProxyModel.h" VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable) : QDialog(parent) diff --git a/launcher/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h index ed30d3f3..ed30d3f3 100644 --- a/launcher/dialogs/VersionSelectDialog.h +++ b/launcher/ui/dialogs/VersionSelectDialog.h diff --git a/launcher/instanceview/AccessibleInstanceView.cpp b/launcher/ui/instanceview/AccessibleInstanceView.cpp index 7de3ac72..7de3ac72 100644 --- a/launcher/instanceview/AccessibleInstanceView.cpp +++ b/launcher/ui/instanceview/AccessibleInstanceView.cpp diff --git a/launcher/instanceview/AccessibleInstanceView.h b/launcher/ui/instanceview/AccessibleInstanceView.h index 9bfd1745..9bfd1745 100644 --- a/launcher/instanceview/AccessibleInstanceView.h +++ b/launcher/ui/instanceview/AccessibleInstanceView.h diff --git a/launcher/instanceview/AccessibleInstanceView_p.h b/launcher/ui/instanceview/AccessibleInstanceView_p.h index 26462f51..26462f51 100644 --- a/launcher/instanceview/AccessibleInstanceView_p.h +++ b/launcher/ui/instanceview/AccessibleInstanceView_p.h diff --git a/launcher/instanceview/InstanceDelegate.cpp b/launcher/ui/instanceview/InstanceDelegate.cpp index 3c4ca63f..3c4ca63f 100644 --- a/launcher/instanceview/InstanceDelegate.cpp +++ b/launcher/ui/instanceview/InstanceDelegate.cpp diff --git a/launcher/instanceview/InstanceDelegate.h b/launcher/ui/instanceview/InstanceDelegate.h index d95279f3..d95279f3 100644 --- a/launcher/instanceview/InstanceDelegate.h +++ b/launcher/ui/instanceview/InstanceDelegate.h diff --git a/launcher/instanceview/InstanceProxyModel.cpp b/launcher/ui/instanceview/InstanceProxyModel.cpp index 76434bd4..d8de93ed 100644 --- a/launcher/instanceview/InstanceProxyModel.cpp +++ b/launcher/ui/instanceview/InstanceProxyModel.cpp @@ -16,7 +16,7 @@ #include "InstanceProxyModel.h" #include "InstanceView.h" -#include "Launcher.h" +#include "Application.h" #include <BaseInstance.h> #include <icons/IconList.h> @@ -34,7 +34,7 @@ QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const QVariant data = QSortFilterProxyModel::data(index, role); if(role == Qt::DecorationRole) { - return QVariant(LAUNCHER->icons()->getIcon(data.toString())); + return QVariant(APPLICATION->icons()->getIcon(data.toString())); } return data; } @@ -59,7 +59,7 @@ bool InstanceProxyModel::subSortLessThan(const QModelIndex &left, const QModelIn { BaseInstance *pdataLeft = static_cast<BaseInstance *>(left.internalPointer()); BaseInstance *pdataRight = static_cast<BaseInstance *>(right.internalPointer()); - QString sortMode = LAUNCHER->settings()->get("InstSortMode").toString(); + QString sortMode = APPLICATION->settings()->get("InstSortMode").toString(); if (sortMode == "LastLaunch") { return pdataLeft->lastLaunch() > pdataRight->lastLaunch(); diff --git a/launcher/instanceview/InstanceProxyModel.h b/launcher/ui/instanceview/InstanceProxyModel.h index bba8d2b5..bba8d2b5 100644 --- a/launcher/instanceview/InstanceProxyModel.h +++ b/launcher/ui/instanceview/InstanceProxyModel.h diff --git a/launcher/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 80dfb6f2..1f044866 100644 --- a/launcher/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -30,7 +30,7 @@ #include "VisualGroup.h" #include <QDebug> -#include <Launcher.h> +#include <Application.h> #include <InstanceList.h> @@ -628,7 +628,7 @@ void InstanceView::dropEvent(QDropEvent *event) return; } auto instanceId = QString::fromUtf8(mimedata->data("application/x-instanceid")); - auto instanceList = LAUNCHER->instances().get(); + auto instanceList = APPLICATION->instances().get(); instanceList->setInstanceGroup(instanceId, group->text); event->setDropAction(Qt::MoveAction); event->accept(); diff --git a/launcher/instanceview/InstanceView.h b/launcher/ui/instanceview/InstanceView.h index 406362e6..406362e6 100644 --- a/launcher/instanceview/InstanceView.h +++ b/launcher/ui/instanceview/InstanceView.h diff --git a/launcher/instanceview/VisualGroup.cpp b/launcher/ui/instanceview/VisualGroup.cpp index 8991fb2d..8991fb2d 100644 --- a/launcher/instanceview/VisualGroup.cpp +++ b/launcher/ui/instanceview/VisualGroup.cpp diff --git a/launcher/instanceview/VisualGroup.h b/launcher/ui/instanceview/VisualGroup.h index 5a743aa1..5a743aa1 100644 --- a/launcher/instanceview/VisualGroup.h +++ b/launcher/ui/instanceview/VisualGroup.h diff --git a/launcher/pagedialog/PageDialog.cpp b/launcher/ui/pagedialog/PageDialog.cpp index 79d7acd3..18d61dc2 100644 --- a/launcher/pagedialog/PageDialog.cpp +++ b/launcher/ui/pagedialog/PageDialog.cpp @@ -20,10 +20,11 @@ #include <QVBoxLayout> #include <QKeyEvent> -#include "Launcher.h" +#include "Application.h" #include "settings/SettingsObject.h" -#include "widgets/IconLabel.h" -#include "widgets/PageContainer.h" + +#include "ui/widgets/IconLabel.h" +#include "ui/widgets/PageContainer.h" PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidget *parent) : QDialog(parent) @@ -45,7 +46,7 @@ PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidge connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close())); connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help())); - restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("PagedGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("PagedGeometry").toByteArray())); } void PageDialog::closeEvent(QCloseEvent *event) @@ -54,7 +55,7 @@ void PageDialog::closeEvent(QCloseEvent *event) if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; - LAUNCHER->settings()->set("PagedGeometry", saveGeometry().toBase64()); + APPLICATION->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; QDialog::closeEvent(event); } diff --git a/launcher/pagedialog/PageDialog.h b/launcher/ui/pagedialog/PageDialog.h index 1029bc30..00d8b725 100644 --- a/launcher/pagedialog/PageDialog.h +++ b/launcher/ui/pagedialog/PageDialog.h @@ -16,7 +16,7 @@ #pragma once #include <QDialog> -#include "pages/BasePageProvider.h" +#include "ui/pages/BasePageProvider.h" class PageContainer; class PageDialog : public QDialog diff --git a/launcher/pages/BasePage.h b/launcher/ui/pages/BasePage.h index 408965d0..408965d0 100644 --- a/launcher/pages/BasePage.h +++ b/launcher/ui/pages/BasePage.h diff --git a/launcher/pages/BasePageContainer.h b/launcher/ui/pages/BasePageContainer.h index f8c7adeb..f8c7adeb 100644 --- a/launcher/pages/BasePageContainer.h +++ b/launcher/ui/pages/BasePageContainer.h diff --git a/launcher/pages/BasePageProvider.h b/launcher/ui/pages/BasePageProvider.h index 7bfaaf3b..873e8dce 100644 --- a/launcher/pages/BasePageProvider.h +++ b/launcher/ui/pages/BasePageProvider.h @@ -15,7 +15,7 @@ #pragma once -#include "pages/BasePage.h" +#include "ui/pages/BasePage.h" #include <memory> #include <functional> diff --git a/launcher/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 4f8b8e9c..816dce47 100644 --- a/launcher/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -22,20 +22,20 @@ #include <QDebug> #include "net/NetJob.h" -#include "Env.h" -#include "dialogs/ProgressDialog.h" -#include "dialogs/LoginDialog.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/SkinUploadDialog.h" +#include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/LoginDialog.h" +#include "ui/dialogs/MSALoginDialog.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/SkinUploadDialog.h" + #include "tasks/Task.h" #include "minecraft/auth/AccountTask.h" #include "minecraft/services/SkinDelete.h" -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" -#include <dialogs/MSALoginDialog.h> #include "Secrets.h" @@ -50,7 +50,7 @@ AccountListPage::AccountListPage(QWidget *parent) ui->listView->setEmptyMode(VersionListView::String); ui->listView->setContextMenuPolicy(Qt::CustomContextMenu); - m_accounts = LAUNCHER->accounts(); + m_accounts = APPLICATION->accounts(); ui->listView->setModel(m_accounts.get()); ui->listView->header()->setSectionResizeMode(0, QHeaderView::Stretch); @@ -68,7 +68,8 @@ AccountListPage::AccountListPage(QWidget *parent) connect(ui->listView, &VersionListView::customContextMenuRequested, this, &AccountListPage::ShowContextMenu); connect(m_accounts.get(), &AccountList::listChanged, this, &AccountListPage::listChanged); - connect(m_accounts.get(), &AccountList::activeAccountChanged, this, &AccountListPage::listChanged); + connect(m_accounts.get(), &AccountList::listActivityChanged, this, &AccountListPage::listChanged); + connect(m_accounts.get(), &AccountList::defaultAccountChanged, this, &AccountListPage::listChanged); updateButtonStates(); @@ -117,11 +118,11 @@ void AccountListPage::on_actionAddMojang_triggered() tr("Please enter your Mojang account email and password to add your account.") ); - if (account != nullptr) + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { - m_accounts->setActiveAccount(account->profileId()); + m_accounts->setDefaultAccount(account); } } } @@ -145,11 +146,11 @@ void AccountListPage::on_actionAddMicrosoft_triggered() tr("Please enter your Mojang account email and password to add your account.") ); - if (account != nullptr) + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { - m_accounts->setActiveAccount(account->profileId()); + m_accounts->setDefaultAccount(account); } } } @@ -187,27 +188,34 @@ void AccountListPage::on_actionSetDefault_triggered() { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>(); - m_accounts->setActiveAccount(account->profileId()); + m_accounts->setDefaultAccount(account); } } void AccountListPage::on_actionNoDefault_triggered() { - m_accounts->setActiveAccount(""); + m_accounts->setDefaultAccount(nullptr); } void AccountListPage::updateButtonStates() { // If there is no selection, disable buttons that require something selected. QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + bool hasSelection = selection.size() > 0; + bool accountIsReady = false; + if (hasSelection) + { + QModelIndex selected = selection.first(); + MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>(); + accountIsReady = !account->isActive(); + } + ui->actionRemove->setEnabled(accountIsReady); + ui->actionSetDefault->setEnabled(accountIsReady); + ui->actionUploadSkin->setEnabled(accountIsReady); + ui->actionDeleteSkin->setEnabled(accountIsReady); + ui->actionRefresh->setEnabled(accountIsReady); - ui->actionRemove->setEnabled(selection.size() > 0); - ui->actionSetDefault->setEnabled(selection.size() > 0); - ui->actionUploadSkin->setEnabled(selection.size() > 0); - ui->actionDeleteSkin->setEnabled(selection.size() > 0); - ui->actionRefresh->setEnabled(selection.size() > 0); - - if(m_accounts->activeAccount().get() == nullptr) { + if(m_accounts->defaultAccount().get() == nullptr) { ui->actionNoDefault->setEnabled(false); ui->actionNoDefault->setChecked(true); } @@ -215,7 +223,6 @@ void AccountListPage::updateButtonStates() ui->actionNoDefault->setEnabled(true); ui->actionNoDefault->setChecked(false); } - } void AccountListPage::on_actionUploadSkin_triggered() diff --git a/launcher/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h index ee81acd1..1c65e708 100644 --- a/launcher/pages/global/AccountListPage.h +++ b/launcher/ui/pages/global/AccountListPage.h @@ -18,10 +18,10 @@ #include <QMainWindow> #include <memory> -#include "pages/BasePage.h" +#include "ui/pages/BasePage.h" #include "minecraft/auth/AccountList.h" -#include "Launcher.h" +#include "Application.h" namespace Ui { @@ -43,10 +43,10 @@ public: } QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("accounts"); + auto icon = APPLICATION->getThemedIcon("accounts"); if(icon.isNull()) { - icon = LAUNCHER->getThemedIcon("noaccount"); + icon = APPLICATION->getThemedIcon("noaccount"); } return icon; } @@ -80,6 +80,6 @@ protected slots: private: void changeEvent(QEvent * event) override; QMenu * createPopupMenu() override; - std::shared_ptr<AccountList> m_accounts; + shared_qobject_ptr<AccountList> m_accounts; Ui::AccountListPage *ui; }; diff --git a/launcher/pages/global/AccountListPage.ui b/launcher/ui/pages/global/AccountListPage.ui index 8af23a2f..29738c02 100644 --- a/launcher/pages/global/AccountListPage.ui +++ b/launcher/ui/pages/global/AccountListPage.ui @@ -116,12 +116,12 @@ <customwidget> <class>VersionListView</class> <extends>QTreeView</extends> - <header>widgets/VersionListView.h</header> + <header>ui/widgets/VersionListView.h</header> </customwidget> <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <resources/> diff --git a/launcher/pages/global/CustomCommandsPage.cpp b/launcher/ui/pages/global/CustomCommandsPage.cpp index 8a5c3445..8541e3c1 100644 --- a/launcher/pages/global/CustomCommandsPage.cpp +++ b/launcher/ui/pages/global/CustomCommandsPage.cpp @@ -32,7 +32,7 @@ bool CustomCommandsPage::apply() void CustomCommandsPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("PreLaunchCommand", commands->prelaunchCommand()); s->set("WrapperCommand", commands->wrapperCommand()); s->set("PostExitCommand", commands->postexitCommand()); @@ -40,7 +40,7 @@ void CustomCommandsPage::applySettings() void CustomCommandsPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); commands->initialize( false, true, diff --git a/launcher/pages/global/CustomCommandsPage.h b/launcher/ui/pages/global/CustomCommandsPage.h index ac69a997..a1155e0e 100644 --- a/launcher/pages/global/CustomCommandsPage.h +++ b/launcher/ui/pages/global/CustomCommandsPage.h @@ -18,9 +18,9 @@ #include <memory> #include <QDialog> -#include "pages/BasePage.h" -#include <Launcher.h> -#include "widgets/CustomCommands.h" +#include "ui/pages/BasePage.h" +#include <Application.h> +#include "ui/widgets/CustomCommands.h" class CustomCommandsPage : public QWidget, public BasePage { @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("custom-commands"); + return APPLICATION->getThemedIcon("custom-commands"); } QString id() const override { diff --git a/launcher/pages/global/ExternalToolsPage.cpp b/launcher/ui/pages/global/ExternalToolsPage.cpp index 7e1a915f..41d900aa 100644 --- a/launcher/pages/global/ExternalToolsPage.cpp +++ b/launcher/ui/pages/global/ExternalToolsPage.cpp @@ -24,7 +24,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" #include <FileSystem.h> -#include "Launcher.h" +#include "Application.h" #include <tools/MCEditTool.h> ExternalToolsPage::ExternalToolsPage(QWidget *parent) : @@ -51,7 +51,7 @@ ExternalToolsPage::~ExternalToolsPage() void ExternalToolsPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString()); ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString()); ui->mceditPathEdit->setText(s->get("MCEditPath").toString()); @@ -61,7 +61,7 @@ void ExternalToolsPage::loadSettings() } void ExternalToolsPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("JProfilerPath", ui->jprofilerPathEdit->text()); s->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); @@ -93,7 +93,7 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->profilers()["jprofiler"]->check(cooked_dir, &error)) + if (!APPLICATION->profilers()["jprofiler"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); continue; @@ -108,7 +108,7 @@ void ExternalToolsPage::on_jprofilerPathBtn_clicked() void ExternalToolsPage::on_jprofilerCheckBtn_clicked() { QString error; - if (!LAUNCHER->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) + if (!APPLICATION->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error)); } @@ -130,7 +130,7 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->profilers()["jvisualvm"]->check(cooked_dir, &error)) + if (!APPLICATION->profilers()["jvisualvm"]->check(cooked_dir, &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); continue; @@ -145,7 +145,7 @@ void ExternalToolsPage::on_jvisualvmPathBtn_clicked() void ExternalToolsPage::on_jvisualvmCheckBtn_clicked() { QString error; - if (!LAUNCHER->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) + if (!APPLICATION->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error)); } @@ -171,7 +171,7 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() break; } QString cooked_dir = FS::NormalizePath(raw_dir); - if (!LAUNCHER->mcedit()->check(cooked_dir, error)) + if (!APPLICATION->mcedit()->check(cooked_dir, error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); continue; @@ -186,7 +186,7 @@ void ExternalToolsPage::on_mceditPathBtn_clicked() void ExternalToolsPage::on_mceditCheckBtn_clicked() { QString error; - if (!LAUNCHER->mcedit()->check(ui->mceditPathEdit->text(), error)) + if (!APPLICATION->mcedit()->check(ui->mceditPathEdit->text(), error)) { QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error)); } diff --git a/launcher/pages/global/ExternalToolsPage.h b/launcher/ui/pages/global/ExternalToolsPage.h index 1d99273a..5ae6148d 100644 --- a/launcher/pages/global/ExternalToolsPage.h +++ b/launcher/ui/pages/global/ExternalToolsPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { class ExternalToolsPage; @@ -38,10 +38,10 @@ public: } QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("externaltools"); + auto icon = APPLICATION->getThemedIcon("externaltools"); if(icon.isNull()) { - icon = LAUNCHER->getThemedIcon("loadermods"); + icon = APPLICATION->getThemedIcon("loadermods"); } return icon; } diff --git a/launcher/pages/global/ExternalToolsPage.ui b/launcher/ui/pages/global/ExternalToolsPage.ui index e79e9388..e79e9388 100644 --- a/launcher/pages/global/ExternalToolsPage.ui +++ b/launcher/ui/pages/global/ExternalToolsPage.ui diff --git a/launcher/pages/global/JavaPage.cpp b/launcher/ui/pages/global/JavaPage.cpp index dd158fcd..bd79f11a 100644 --- a/launcher/pages/global/JavaPage.cpp +++ b/launcher/ui/pages/global/JavaPage.cpp @@ -22,14 +22,14 @@ #include <QDir> #include <QTabBar> -#include "dialogs/VersionSelectDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" #include "java/JavaUtils.h" #include "java/JavaInstallList.h" #include "settings/SettingsObject.h" #include <FileSystem.h> -#include "Launcher.h" +#include "Application.h" #include <sys.h> JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) @@ -55,7 +55,7 @@ bool JavaPage::apply() void JavaPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory int min = ui->minMemSpinBox->value(); @@ -79,7 +79,7 @@ void JavaPage::applySettings() } void JavaPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory int min = s->get("MinMemAlloc").toInt(); int max = s->get("MaxMemAlloc").toInt(); @@ -104,7 +104,7 @@ void JavaPage::on_javaDetectBtn_clicked() { JavaInstallPtr java; - VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(APPLICATION->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/global/JavaPage.h b/launcher/ui/pages/global/JavaPage.h index 93a586cd..8f9b3323 100644 --- a/launcher/pages/global/JavaPage.h +++ b/launcher/ui/pages/global/JavaPage.h @@ -17,9 +17,9 @@ #include <memory> #include <QDialog> -#include "pages/BasePage.h" +#include "ui/pages/BasePage.h" #include "JavaCommon.h" -#include <Launcher.h> +#include <Application.h> #include <QObjectPtr.h> class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("java"); + return APPLICATION->getThemedIcon("java"); } QString id() const override { diff --git a/launcher/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index b67e9994..b67e9994 100644 --- a/launcher/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui diff --git a/launcher/pages/global/LanguagePage.cpp b/launcher/ui/pages/global/LanguagePage.cpp index 409bf7d0..359fdeeb 100644 --- a/launcher/pages/global/LanguagePage.cpp +++ b/launcher/ui/pages/global/LanguagePage.cpp @@ -1,6 +1,6 @@ #include "LanguagePage.h" -#include "widgets/LanguageSelectionWidget.h" +#include "ui/widgets/LanguageSelectionWidget.h" #include <QVBoxLayout> LanguagePage::LanguagePage(QWidget* parent) : @@ -26,7 +26,7 @@ bool LanguagePage::apply() void LanguagePage::applySettings() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); } diff --git a/launcher/pages/global/LanguagePage.h b/launcher/ui/pages/global/LanguagePage.h index 22db8f94..b1dd05ad 100644 --- a/launcher/pages/global/LanguagePage.h +++ b/launcher/ui/pages/global/LanguagePage.h @@ -16,8 +16,8 @@ #pragma once #include <memory> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include <QWidget> class LanguageSelectionWidget; @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("language"); + return APPLICATION->getThemedIcon("language"); } QString id() const override { diff --git a/launcher/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 5f8d87d8..2eb73e44 100644 --- a/launcher/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -25,9 +25,9 @@ #include "settings/SettingsObject.h" #include <FileSystem.h> -#include "Launcher.h" +#include "Application.h" #include "BuildConfig.h" -#include "themes/ITheme.h" +#include "ui/themes/ITheme.h" #include <QApplication> #include <QProcess> @@ -53,20 +53,20 @@ LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::Launch defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); - m_languageModel = LAUNCHER->translations(); + m_languageModel = APPLICATION->translations(); loadSettings(); if(BuildConfig.UPDATER_ENABLED) { - QObject::connect(LAUNCHER->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &LauncherPage::refreshUpdateChannelList); + QObject::connect(APPLICATION->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &LauncherPage::refreshUpdateChannelList); - if (LAUNCHER->updateChecker()->hasChannels()) + if (APPLICATION->updateChecker()->hasChannels()) { refreshUpdateChannelList(); } else { - LAUNCHER->updateChecker()->updateChanList(false); + APPLICATION->updateChecker()->updateChanList(false); } } else @@ -171,7 +171,7 @@ void LauncherPage::refreshUpdateChannelList() QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateChannelSelectionChanged(int))); - QList<UpdateChecker::ChannelListEntry> channelList = LAUNCHER->updateChecker()->getChannelList(); + QList<UpdateChecker::ChannelListEntry> channelList = APPLICATION->updateChecker()->getChannelList(); ui->updateChannelComboBox->clear(); int selection = -1; for (int i = 0; i < channelList.count(); i++) @@ -216,7 +216,7 @@ void LauncherPage::updateChannelSelectionChanged(int index) void LauncherPage::refreshUpdateChannelDesc() { // Get the channel list. - QList<UpdateChecker::ChannelListEntry> channelList = LAUNCHER->updateChecker()->getChannelList(); + QList<UpdateChecker::ChannelListEntry> channelList = APPLICATION->updateChecker()->getChannelList(); int selectedIndex = ui->updateChannelComboBox->currentIndex(); if (selectedIndex < 0) { @@ -237,7 +237,7 @@ void LauncherPage::refreshUpdateChannelDesc() void LauncherPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); if (ui->resetNotificationsBtn->isChecked()) { @@ -283,7 +283,7 @@ void LauncherPage::applySettings() if(original != s->get("IconTheme")) { - LAUNCHER->setIconTheme(s->get("IconTheme").toString()); + APPLICATION->setIconTheme(s->get("IconTheme").toString()); } auto originalAppTheme = s->get("ApplicationTheme").toString(); @@ -291,7 +291,7 @@ void LauncherPage::applySettings() if(originalAppTheme != newAppTheme) { s->set("ApplicationTheme", newAppTheme); - LAUNCHER->setApplicationTheme(newAppTheme, false); + APPLICATION->setApplicationTheme(newAppTheme, false); } // Console settings @@ -330,7 +330,7 @@ void LauncherPage::applySettings() } void LauncherPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Updates ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); m_currentUpdateChannel = s->get("UpdateChannel").toString(); @@ -375,7 +375,7 @@ void LauncherPage::loadSettings() { auto currentTheme = s->get("ApplicationTheme").toString(); - auto themes = LAUNCHER->getValidApplicationThemes(); + auto themes = APPLICATION->getValidApplicationThemes(); int idx = 0; for(auto &theme: themes) { @@ -392,12 +392,12 @@ void LauncherPage::loadSettings() ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool()); - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); QFont consoleFont(fontFamily); ui->consoleFont->setCurrentFont(consoleFont); bool conversionOk = true; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/global/LauncherPage.h b/launcher/ui/pages/global/LauncherPage.h index e622ec48..4d0cf3c9 100644 --- a/launcher/pages/global/LauncherPage.h +++ b/launcher/ui/pages/global/LauncherPage.h @@ -19,9 +19,9 @@ #include <QDialog> #include "java/JavaChecker.h" -#include "pages/BasePage.h" -#include <Launcher.h> -#include "ColorCache.h" +#include "ui/pages/BasePage.h" +#include <Application.h> +#include "ui/ColorCache.h" #include <translations/TranslationsModel.h> class QTextCharFormat; @@ -46,7 +46,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("launcher"); + return APPLICATION->getThemedIcon("launcher"); } QString id() const override { diff --git a/launcher/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 62a66d73..62a66d73 100644 --- a/launcher/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui diff --git a/launcher/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index 342941f4..c763f8ac 100644 --- a/launcher/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -21,7 +21,7 @@ #include <QTabBar> #include "settings/SettingsObject.h" -#include "Launcher.h" +#include "Application.h" MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage) { @@ -56,7 +56,7 @@ void MinecraftPage::on_maximizedCheckBox_clicked(bool checked) void MinecraftPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Window Size s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); @@ -75,7 +75,7 @@ void MinecraftPage::applySettings() void MinecraftPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Window Size ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); diff --git a/launcher/pages/global/MinecraftPage.h b/launcher/ui/pages/global/MinecraftPage.h index 0fc6cc8e..42626d94 100644 --- a/launcher/pages/global/MinecraftPage.h +++ b/launcher/ui/pages/global/MinecraftPage.h @@ -19,8 +19,8 @@ #include <QDialog> #include "java/JavaChecker.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("minecraft"); + return APPLICATION->getThemedIcon("minecraft"); } QString id() const override { diff --git a/launcher/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 857b8cfb..857b8cfb 100644 --- a/launcher/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui diff --git a/launcher/pages/global/PasteEEPage.cpp b/launcher/ui/pages/global/PasteEEPage.cpp index 9f7a7efb..4b375d9a 100644 --- a/launcher/pages/global/PasteEEPage.cpp +++ b/launcher/ui/pages/global/PasteEEPage.cpp @@ -23,7 +23,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" -#include "Launcher.h" +#include "Application.h" PasteEEPage::PasteEEPage(QWidget *parent) : QWidget(parent), @@ -42,7 +42,7 @@ PasteEEPage::~PasteEEPage() void PasteEEPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); QString keyToUse = s->get("PasteEEAPIKey").toString(); if(keyToUse == "multimc") { @@ -57,7 +57,7 @@ void PasteEEPage::loadSettings() void PasteEEPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); QString pasteKeyToUse; if (ui->customButton->isChecked()) diff --git a/launcher/pages/global/PasteEEPage.h b/launcher/ui/pages/global/PasteEEPage.h index c99cd51e..a1c7d434 100644 --- a/launcher/pages/global/PasteEEPage.h +++ b/launcher/ui/pages/global/PasteEEPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { class PasteEEPage; @@ -38,7 +38,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } QString id() const override { diff --git a/launcher/pages/global/PasteEEPage.ui b/launcher/ui/pages/global/PasteEEPage.ui index 10883781..10883781 100644 --- a/launcher/pages/global/PasteEEPage.ui +++ b/launcher/ui/pages/global/PasteEEPage.ui diff --git a/launcher/pages/global/ProxyPage.cpp b/launcher/ui/pages/global/ProxyPage.cpp index d4e767e1..5bc8199e 100644 --- a/launcher/pages/global/ProxyPage.cpp +++ b/launcher/ui/pages/global/ProxyPage.cpp @@ -19,8 +19,8 @@ #include <QTabBar> #include "settings/SettingsObject.h" -#include "Launcher.h" -#include "Env.h" +#include "Application.h" +#include "Application.h" ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage) { @@ -58,7 +58,7 @@ void ProxyPage::proxyChanged(int) void ProxyPage::applySettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Proxy QString proxyType = "None"; @@ -77,12 +77,17 @@ void ProxyPage::applySettings() s->set("ProxyUser", ui->proxyUserEdit->text()); s->set("ProxyPass", ui->proxyPassEdit->text()); - ENV.updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(), - ui->proxyUserEdit->text(), ui->proxyPassEdit->text()); + APPLICATION->updateProxySettings( + proxyType, + ui->proxyAddrEdit->text(), + ui->proxyPortEdit->value(), + ui->proxyUserEdit->text(), + ui->proxyPassEdit->text() + ); } void ProxyPage::loadSettings() { - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Proxy QString proxyType = s->get("ProxyType").toString(); if (proxyType == "Default") diff --git a/launcher/pages/global/ProxyPage.h b/launcher/ui/pages/global/ProxyPage.h index 90c33c9d..6698c349 100644 --- a/launcher/pages/global/ProxyPage.h +++ b/launcher/ui/pages/global/ProxyPage.h @@ -18,8 +18,8 @@ #include <memory> #include <QDialog> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { @@ -40,7 +40,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("proxy"); + return APPLICATION->getThemedIcon("proxy"); } QString id() const override { diff --git a/launcher/pages/global/ProxyPage.ui b/launcher/ui/pages/global/ProxyPage.ui index 347fa86c..347fa86c 100644 --- a/launcher/pages/global/ProxyPage.ui +++ b/launcher/ui/pages/global/ProxyPage.ui diff --git a/launcher/pages/instance/GameOptionsPage.cpp b/launcher/ui/pages/instance/GameOptionsPage.cpp index 782f2ab3..782f2ab3 100644 --- a/launcher/pages/instance/GameOptionsPage.cpp +++ b/launcher/ui/pages/instance/GameOptionsPage.cpp diff --git a/launcher/pages/instance/GameOptionsPage.h b/launcher/ui/pages/instance/GameOptionsPage.h index ca7e31b1..878903eb 100644 --- a/launcher/pages/instance/GameOptionsPage.h +++ b/launcher/ui/pages/instance/GameOptionsPage.h @@ -18,8 +18,8 @@ #include <QWidget> #include <QString> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("settings"); + return APPLICATION->getThemedIcon("settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/GameOptionsPage.ui b/launcher/ui/pages/instance/GameOptionsPage.ui index f0a5ce0e..f0a5ce0e 100644 --- a/launcher/pages/instance/GameOptionsPage.ui +++ b/launcher/ui/pages/instance/GameOptionsPage.ui diff --git a/launcher/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index c83832c6..b0e18af4 100644 --- a/launcher/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -5,14 +5,17 @@ #include <QDialog> #include <QMessageBox> -#include "dialogs/VersionSelectDialog.h" +#include <sys.h> + +#include "ui/dialogs/VersionSelectDialog.h" +#include "ui/widgets/CustomCommands.h" + #include "JavaCommon.h" -#include "Launcher.h" +#include "Application.h" + +#include "java/JavaInstallList.h" +#include "FileSystem.h" -#include <java/JavaInstallList.h> -#include <FileSystem.h> -#include <sys.h> -#include <widgets/CustomCommands.h> InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) @@ -22,8 +25,8 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) auto sysMB = Sys::getSystemRam() / Sys::mebibyte; ui->maxMemSpinBox->setMaximum(sysMB); connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked); - connect(LAUNCHER, &Launcher::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); - connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); + connect(APPLICATION, &Application::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); + connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); loadSettings(); } @@ -41,13 +44,13 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) { switch(ui->settingsTabs->currentIndex()) { case 0: - LAUNCHER->ShowGlobalSettings(this, "java-settings"); + APPLICATION->ShowGlobalSettings(this, "java-settings"); return; case 1: - LAUNCHER->ShowGlobalSettings(this, "minecraft-settings"); + APPLICATION->ShowGlobalSettings(this, "minecraft-settings"); return; case 2: - LAUNCHER->ShowGlobalSettings(this, "custom-commands"); + APPLICATION->ShowGlobalSettings(this, "custom-commands"); return; } } @@ -278,7 +281,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() { JavaInstallPtr java; - VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(APPLICATION->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/instance/InstanceSettingsPage.h b/launcher/ui/pages/instance/InstanceSettingsPage.h index a039101c..5c8c8e66 100644 --- a/launcher/pages/instance/InstanceSettingsPage.h +++ b/launcher/ui/pages/instance/InstanceSettingsPage.h @@ -20,9 +20,9 @@ #include "java/JavaChecker.h" #include "BaseInstance.h" #include <QObjectPtr.h> -#include "pages/BasePage.h" +#include "ui/pages/BasePage.h" #include "JavaCommon.h" -#include "Launcher.h" +#include "Application.h" class JavaChecker; namespace Ui @@ -43,7 +43,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("instance-settings"); + return APPLICATION->getThemedIcon("instance-settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 35cd7335..729f8e2a 100644 --- a/launcher/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -511,7 +511,7 @@ <customwidget> <class>CustomCommands</class> <extends>QWidget</extends> - <header>widgets/CustomCommands.h</header> + <header>ui/widgets/CustomCommands.h</header> <container>1</container> </customwidget> </customwidgets> diff --git a/launcher/pages/instance/LegacyUpgradePage.cpp b/launcher/ui/pages/instance/LegacyUpgradePage.cpp index b12174fa..cb78af02 100644 --- a/launcher/pages/instance/LegacyUpgradePage.cpp +++ b/launcher/ui/pages/instance/LegacyUpgradePage.cpp @@ -4,9 +4,10 @@ #include "InstanceList.h" #include "minecraft/legacy/LegacyInstance.h" #include "minecraft/legacy/LegacyUpgradeTask.h" -#include "Launcher.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/ProgressDialog.h" +#include "Application.h" + +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent) : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst) @@ -38,9 +39,9 @@ void LegacyUpgradePage::on_upgradeButton_clicked() QString newName = tr("%1 (Migrated)").arg(m_inst->name()); auto upgradeTask = new LegacyUpgradeTask(m_inst); upgradeTask->setName(newName); - upgradeTask->setGroup(LAUNCHER->instances()->getInstanceGroup(m_inst->id())); + upgradeTask->setGroup(APPLICATION->instances()->getInstanceGroup(m_inst->id())); upgradeTask->setIcon(m_inst->iconKey()); - unique_qobject_ptr<Task> task(LAUNCHER->instances()->wrapInstanceTask(upgradeTask)); + unique_qobject_ptr<Task> task(APPLICATION->instances()->wrapInstanceTask(upgradeTask)); runModalTask(task.get()); } diff --git a/launcher/pages/instance/LegacyUpgradePage.h b/launcher/ui/pages/instance/LegacyUpgradePage.h index d8e98f6b..7c51956b 100644 --- a/launcher/pages/instance/LegacyUpgradePage.h +++ b/launcher/ui/pages/instance/LegacyUpgradePage.h @@ -18,8 +18,8 @@ #include <QWidget> #include "minecraft/legacy/LegacyInstance.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" namespace Ui @@ -40,7 +40,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("checkupdate"); + return APPLICATION->getThemedIcon("checkupdate"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LegacyUpgradePage.ui b/launcher/ui/pages/instance/LegacyUpgradePage.ui index 085919e3..085919e3 100644 --- a/launcher/pages/instance/LegacyUpgradePage.ui +++ b/launcher/ui/pages/instance/LegacyUpgradePage.ui diff --git a/launcher/pages/instance/LogPage.cpp b/launcher/ui/pages/instance/LogPage.cpp index 2846dc51..b66c6cc7 100644 --- a/launcher/pages/instance/LogPage.cpp +++ b/launcher/ui/pages/instance/LogPage.cpp @@ -1,16 +1,18 @@ #include "LogPage.h" #include "ui_LogPage.h" -#include "Launcher.h" +#include "Application.h" #include <QIcon> #include <QScrollBar> #include <QShortcut> #include "launch/LaunchTask.h" -#include <settings/Setting.h> -#include "GuiUtil.h" -#include <ColorCache.h> +#include "settings/Setting.h" + +#include "ui/GuiUtil.h" +#include "ui/ColorCache.h" + #include <BuildConfig.h> class LogFormatProxyModel : public QIdentityProxyModel @@ -125,9 +127,9 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent) // set up fonts in the log proxy { - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/LogPage.h b/launcher/ui/pages/instance/LogPage.h index 285296cd..cab25563 100644 --- a/launcher/pages/instance/LogPage.h +++ b/launcher/ui/pages/instance/LogPage.h @@ -19,8 +19,8 @@ #include "BaseInstance.h" #include "launch/LaunchTask.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { @@ -42,7 +42,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LogPage.ui b/launcher/ui/pages/instance/LogPage.ui index 4843d7c3..ccfc1551 100644 --- a/launcher/pages/instance/LogPage.ui +++ b/launcher/ui/pages/instance/LogPage.ui @@ -163,7 +163,7 @@ <customwidget> <class>LogView</class> <extends>QPlainTextEdit</extends> - <header>widgets/LogView.h</header> + <header>ui/widgets/LogView.h</header> </customwidget> </customwidgets> <tabstops> diff --git a/launcher/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index caa81958..e63b1434 100644 --- a/launcher/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -21,17 +21,20 @@ #include <QKeyEvent> #include <QAbstractItemModel> #include <QMenu> +#include <QSortFilterProxyModel> + +#include "Application.h" + +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/GuiUtil.h" + +#include "DesktopServices.h" -#include "Launcher.h" -#include "dialogs/CustomMessageBox.h" -#include <GuiUtil.h> #include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/Mod.h" #include "minecraft/VersionFilterData.h" #include "minecraft/PackProfile.h" -#include <DesktopServices.h> -#include <QSortFilterProxyModel> #include "Version.h" namespace { @@ -301,7 +304,7 @@ void ModFolderPage::on_actionAdd_triggered() tr("Select %1", "Select whatever type of files the page contains. Example: 'Loader Mods'") .arg(m_displayName), - m_fileSelectionFilter.arg(m_displayName), LAUNCHER->settings()->get("CentralModsDir").toString(), + m_fileSelectionFilter.arg(m_displayName), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.empty()) { diff --git a/launcher/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 38fcc6a5..8ef7559b 100644 --- a/launcher/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -18,8 +18,9 @@ #include <QMainWindow> #include "minecraft/MinecraftInstance.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" + +#include <Application.h> class ModFolderModel; namespace Ui @@ -54,7 +55,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon(m_iconName); + return APPLICATION->getThemedIcon(m_iconName); } virtual QString id() const override { diff --git a/launcher/pages/instance/ModFolderPage.ui b/launcher/ui/pages/instance/ModFolderPage.ui index 954a0167..0fb51e84 100644 --- a/launcher/pages/instance/ModFolderPage.ui +++ b/launcher/ui/pages/instance/ModFolderPage.ui @@ -141,18 +141,18 @@ <customwidget> <class>ModListView</class> <extends>QTreeView</extends> - <header>widgets/ModListView.h</header> + <header>ui/widgets/ModListView.h</header> </customwidget> <customwidget> <class>MCModInfoFrame</class> <extends>QFrame</extends> - <header>widgets/MCModInfoFrame.h</header> + <header>ui/widgets/MCModInfoFrame.h</header> <container>1</container> </customwidget> <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <tabstops> diff --git a/launcher/pages/instance/NotesPage.cpp b/launcher/ui/pages/instance/NotesPage.cpp index fa966c91..fa966c91 100644 --- a/launcher/pages/instance/NotesPage.cpp +++ b/launcher/ui/pages/instance/NotesPage.cpp diff --git a/launcher/pages/instance/NotesPage.h b/launcher/ui/pages/instance/NotesPage.h index 1bdb352d..539401ee 100644 --- a/launcher/pages/instance/NotesPage.h +++ b/launcher/ui/pages/instance/NotesPage.h @@ -18,8 +18,8 @@ #include <QWidget> #include "BaseInstance.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { @@ -39,9 +39,9 @@ public: } virtual QIcon icon() const override { - auto icon = LAUNCHER->getThemedIcon("notes"); + auto icon = APPLICATION->getThemedIcon("notes"); if(icon.isNull()) - icon = LAUNCHER->getThemedIcon("news"); + icon = APPLICATION->getThemedIcon("news"); return icon; } virtual QString id() const override diff --git a/launcher/pages/instance/NotesPage.ui b/launcher/ui/pages/instance/NotesPage.ui index 67cb261c..67cb261c 100644 --- a/launcher/pages/instance/NotesPage.ui +++ b/launcher/ui/pages/instance/NotesPage.ui diff --git a/launcher/pages/instance/OtherLogsPage.cpp b/launcher/ui/pages/instance/OtherLogsPage.cpp index 31cd44ed..0131c5c1 100644 --- a/launcher/pages/instance/OtherLogsPage.cpp +++ b/launcher/ui/pages/instance/OtherLogsPage.cpp @@ -18,7 +18,8 @@ #include <QMessageBox> -#include "GuiUtil.h" +#include "ui/GuiUtil.h" + #include "RecursiveFileSystemWatcher.h" #include <GZip.h> #include <FileSystem.h> @@ -129,9 +130,9 @@ void OtherLogsPage::on_btnReload_clicked() { auto setPlainText = [&](const QString & text) { - QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); + QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h index 25f127f6..b2b2a91b 100644 --- a/launcher/pages/instance/OtherLogsPage.h +++ b/launcher/ui/pages/instance/OtherLogsPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include <pathmatcher/IPathMatcher.h> namespace Ui @@ -46,7 +46,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("log"); + return APPLICATION->getThemedIcon("log"); } QString helpPage() const override { diff --git a/launcher/pages/instance/OtherLogsPage.ui b/launcher/ui/pages/instance/OtherLogsPage.ui index 56ff3b62..56ff3b62 100644 --- a/launcher/pages/instance/OtherLogsPage.ui +++ b/launcher/ui/pages/instance/OtherLogsPage.ui diff --git a/launcher/pages/instance/ResourcePackPage.h b/launcher/ui/pages/instance/ResourcePackPage.h index 1486bf52..1486bf52 100644 --- a/launcher/pages/instance/ResourcePackPage.h +++ b/launcher/ui/pages/instance/ResourcePackPage.h diff --git a/launcher/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 172e2eb3..06c4379f 100644 --- a/launcher/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -15,10 +15,11 @@ #include <QKeyEvent> #include <QMenu> -#include <Launcher.h> +#include <Application.h> + +#include "ui/dialogs/ProgressDialog.h" +#include "ui/dialogs/CustomMessageBox.h" -#include "dialogs/ProgressDialog.h" -#include "dialogs/CustomMessageBox.h" #include "net/NetJob.h" #include "screenshots/ImgurUpload.h" #include "screenshots/ImgurAlbumCreation.h" @@ -104,7 +105,7 @@ public: { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared<SharedIconCache>(); - m_thumbnailCache->add("placeholder", LAUNCHER->getThemedIcon("screenshot-placeholder")); + m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); // FIXME: the watched file set is not updated when files are removed } @@ -302,8 +303,8 @@ void ScreenshotsPage::on_actionUpload_triggered() if (selection.isEmpty()) return; - QList<ScreenshotPtr> uploaded; - auto job = NetJobPtr(new NetJob("Screenshot Upload")); + QList<ScreenShot::Ptr> uploaded; + auto job = NetJob::Ptr(new NetJob("Screenshot Upload")); if(selection.size() < 2) { auto item = selection.at(0); @@ -344,11 +345,11 @@ void ScreenshotsPage::on_actionUpload_triggered() job->addNetAction(ImgurUpload::make(screenshot)); } SequentialTask task; - auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation")); + auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation")); auto imgurAlbum = ImgurAlbumCreation::make(uploaded); albumTask->addNetAction(imgurAlbum); - task.addTask(job.unwrap()); - task.addTask(albumTask.unwrap()); + task.addTask(job); + task.addTask(albumTask); m_uploadActive = true; ProgressDialog prog(this); if (prog.execWithTask(&task) != QDialog::Accepted) diff --git a/launcher/pages/instance/ScreenshotsPage.h b/launcher/ui/pages/instance/ScreenshotsPage.h index 01f26642..d2f44837 100644 --- a/launcher/pages/instance/ScreenshotsPage.h +++ b/launcher/ui/pages/instance/ScreenshotsPage.h @@ -17,8 +17,8 @@ #include <QMainWindow> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> class QFileSystemModel; class QIdentityProxyModel; @@ -53,7 +53,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("screenshots"); + return APPLICATION->getThemedIcon("screenshots"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ScreenshotsPage.ui b/launcher/ui/pages/instance/ScreenshotsPage.ui index f11f4cd4..ec461087 100644 --- a/launcher/pages/instance/ScreenshotsPage.ui +++ b/launcher/ui/pages/instance/ScreenshotsPage.ui @@ -79,7 +79,7 @@ <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <resources/> diff --git a/launcher/pages/instance/ServersPage.cpp b/launcher/ui/pages/instance/ServersPage.cpp index 6c55fdac..8116d2bf 100644 --- a/launcher/pages/instance/ServersPage.cpp +++ b/launcher/ui/pages/instance/ServersPage.cpp @@ -324,7 +324,7 @@ public: if(px.loadFromData(bytes)) return QIcon(px); } - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } case Qt::DisplayRole: return m_servers[row].m_name; @@ -762,7 +762,7 @@ void ServersPage::on_actionMove_Down_triggered() void ServersPage::on_actionJoin_triggered() { const auto &address = m_model->at(currentServer)->m_address; - LAUNCHER->launch(m_inst, true, nullptr, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address))); + APPLICATION->launch(m_inst, true, nullptr, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address))); } #include "ServersPage.moc" diff --git a/launcher/pages/instance/ServersPage.h b/launcher/ui/pages/instance/ServersPage.h index 63f3b9e3..d91da2ae 100644 --- a/launcher/pages/instance/ServersPage.h +++ b/launcher/ui/pages/instance/ServersPage.h @@ -18,8 +18,8 @@ #include <QMainWindow> #include <QString> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> namespace Ui { @@ -47,7 +47,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ServersPage.ui b/launcher/ui/pages/instance/ServersPage.ui index d89b7cba..e8f79cf2 100644 --- a/launcher/pages/instance/ServersPage.ui +++ b/launcher/ui/pages/instance/ServersPage.ui @@ -180,7 +180,7 @@ <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <tabstops> diff --git a/launcher/pages/instance/ShaderPackPage.h b/launcher/ui/pages/instance/ShaderPackPage.h index 36724992..36724992 100644 --- a/launcher/pages/instance/ShaderPackPage.h +++ b/launcher/ui/pages/instance/ShaderPackPage.h diff --git a/launcher/pages/instance/TexturePackPage.h b/launcher/ui/pages/instance/TexturePackPage.h index 3f04997d..3f04997d 100644 --- a/launcher/pages/instance/TexturePackPage.h +++ b/launcher/ui/pages/instance/TexturePackPage.h diff --git a/launcher/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 103f0c7a..715059ff 100644 --- a/launcher/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -13,30 +13,29 @@ * limitations under the License. */ -#include "Launcher.h" +#include "Application.h" #include <QMessageBox> #include <QLabel> #include <QEvent> #include <QKeyEvent> #include <QMenu> - -#include "VersionPage.h" -#include "ui_VersionPage.h" - -#include "dialogs/CustomMessageBox.h" -#include "dialogs/VersionSelectDialog.h" -#include "dialogs/NewComponentDialog.h" - -#include "dialogs/ProgressDialog.h" -#include <GuiUtil.h> - #include <QAbstractItemModel> #include <QMessageBox> #include <QListView> #include <QString> #include <QUrl> +#include "VersionPage.h" +#include "ui_VersionPage.h" + +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/VersionSelectDialog.h" +#include "ui/dialogs/NewComponentDialog.h" +#include "ui/dialogs/ProgressDialog.h" + +#include "ui/GuiUtil.h" + #include "minecraft/PackProfile.h" #include "minecraft/auth/AccountList.h" #include "minecraft/mod/Mod.h" @@ -45,8 +44,8 @@ #include "Version.h" #include "DesktopServices.h" -#include <meta/Index.h> -#include <meta/VersionList.h> +#include "meta/Index.h" +#include "meta/VersionList.h" class IconProxy : public QIdentityProxyModel { @@ -70,14 +69,14 @@ public: auto string = var.toString(); if(string == "warning") { - return LAUNCHER->getThemedIcon("status-yellow"); + return APPLICATION->getThemedIcon("status-yellow"); } else if(string == "error") { - return LAUNCHER->getThemedIcon("status-bad"); + return APPLICATION->getThemedIcon("status-bad"); } } - return LAUNCHER->getThemedIcon("status-good"); + return APPLICATION->getThemedIcon("status-good"); } return var; } @@ -93,7 +92,7 @@ private: QIcon VersionPage::icon() const { - return LAUNCHER->icons()->getIcon(m_inst->iconKey()); + return APPLICATION->icons()->getIcon(m_inst->iconKey()); } bool VersionPage::shouldDisplay() const { @@ -297,7 +296,7 @@ void VersionPage::on_actionInstall_mods_triggered() void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() { - auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!list.empty()) { m_profile->installJarMods(list); @@ -307,7 +306,7 @@ void VersionPage::on_actionAdd_to_Minecraft_jar_triggered() void VersionPage::on_actionReplace_Minecraft_jar_triggered() { - auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), APPLICATION->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!jarPath.isEmpty()) { m_profile->installCustomJar(jarPath); @@ -395,7 +394,7 @@ void VersionPage::on_actionChange_version_triggered() void VersionPage::on_actionDownload_All_triggered() { - if (!LAUNCHER->accounts()->anyAccountIsValid()) + if (!APPLICATION->accounts()->anyAccountIsValid()) { CustomMessageBox::selectable( this, tr("Error"), @@ -420,7 +419,7 @@ void VersionPage::on_actionDownload_All_triggered() void VersionPage::on_actionInstall_Forge_triggered() { - auto vlist = ENV.metadataIndex()->get("net.minecraftforge"); + auto vlist = APPLICATION->metadataIndex()->get("net.minecraftforge"); if(!vlist) { return; @@ -449,7 +448,7 @@ void VersionPage::on_actionInstall_Forge_triggered() void VersionPage::on_actionInstall_Fabric_triggered() { - auto vlist = ENV.metadataIndex()->get("net.fabricmc.fabric-loader"); + auto vlist = APPLICATION->metadataIndex()->get("net.fabricmc.fabric-loader"); if(!vlist) { return; @@ -494,7 +493,7 @@ void VersionPage::on_actionAdd_Empty_triggered() void VersionPage::on_actionInstall_LiteLoader_triggered() { - auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader"); + auto vlist = APPLICATION->metadataIndex()->get("com.mumfrey.liteloader"); if(!vlist) { return; @@ -614,7 +613,7 @@ void VersionPage::on_actionEdit_triggered() qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; return; } - LAUNCHER->openJsonEditor(filename); + APPLICATION->openJsonEditor(filename); } void VersionPage::on_actionRevert_triggered() diff --git a/launcher/pages/instance/VersionPage.h b/launcher/ui/pages/instance/VersionPage.h index b5b4a6f5..b5ce4064 100644 --- a/launcher/pages/instance/VersionPage.h +++ b/launcher/ui/pages/instance/VersionPage.h @@ -19,7 +19,7 @@ #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "pages/BasePage.h" +#include "ui/pages/BasePage.h" namespace Ui { diff --git a/launcher/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index 84d06e2e..a4990ff3 100644 --- a/launcher/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -266,18 +266,18 @@ <customwidget> <class>ModListView</class> <extends>QTreeView</extends> - <header>widgets/ModListView.h</header> + <header>ui/widgets/ModListView.h</header> </customwidget> <customwidget> <class>MCModInfoFrame</class> <extends>QFrame</extends> - <header>widgets/MCModInfoFrame.h</header> + <header>ui/widgets/MCModInfoFrame.h</header> <container>1</container> </customwidget> <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <resources/> diff --git a/launcher/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index d25f23a8..d2bf63bd 100644 --- a/launcher/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -16,7 +16,7 @@ #include "WorldListPage.h" #include "ui_WorldListPage.h" #include "minecraft/WorldList.h" -#include <DesktopServices.h> + #include <QEvent> #include <QMenu> #include <QKeyEvent> @@ -24,12 +24,16 @@ #include <QMessageBox> #include <QTreeView> #include <QInputDialog> -#include <tools/MCEditTool.h> - -#include "Launcher.h" -#include <GuiUtil.h> #include <QProcess> -#include <FileSystem.h> + +#include "tools/MCEditTool.h" +#include "FileSystem.h" + +#include "ui/GuiUtil.h" +#include "DesktopServices.h" + +#include "Application.h" + class WorldListProxyModel : public QSortFilterProxyModel { @@ -48,7 +52,7 @@ public: auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString(); if(iconFile.isNull()) { // NOTE: Minecraft uses the same placeholder for servers AND worlds - return LAUNCHER->getThemedIcon("unknown_server"); + return APPLICATION->getThemedIcon("unknown_server"); } return QIcon(iconFile); } @@ -218,7 +222,7 @@ void WorldListPage::on_actionCopy_Seed_triggered() return; } int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong(); - LAUNCHER->clipboard()->setText(QString::number(seed)); + APPLICATION->clipboard()->setText(QString::number(seed)); } void WorldListPage::on_actionMCEdit_triggered() @@ -226,7 +230,7 @@ void WorldListPage::on_actionMCEdit_triggered() if(m_mceditStarting) return; - auto mcedit = LAUNCHER->mcedit(); + auto mcedit = APPLICATION->mcedit(); const QString mceditPath = mcedit->path(); diff --git a/launcher/pages/instance/WorldListPage.h b/launcher/ui/pages/instance/WorldListPage.h index b90d7ad1..e07d5794 100644 --- a/launcher/pages/instance/WorldListPage.h +++ b/launcher/ui/pages/instance/WorldListPage.h @@ -18,8 +18,8 @@ #include <QMainWindow> #include "minecraft/MinecraftInstance.h" -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include <LoggedProcess.h> class WorldList; @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("worlds"); + return APPLICATION->getThemedIcon("worlds"); } virtual QString id() const override { diff --git a/launcher/pages/instance/WorldListPage.ui b/launcher/ui/pages/instance/WorldListPage.ui index ed078d94..7c68bfae 100644 --- a/launcher/pages/instance/WorldListPage.ui +++ b/launcher/ui/pages/instance/WorldListPage.ui @@ -153,7 +153,7 @@ <customwidget> <class>WideBar</class> <extends>QToolBar</extends> - <header>widgets/WideBar.h</header> + <header>ui/widgets/WideBar.h</header> </customwidget> </customwidgets> <resources/> diff --git a/launcher/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index dd02e839..c9e24ead 100644 --- a/launcher/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -1,11 +1,13 @@ #include "ImportPage.h" #include "ui_ImportPage.h" -#include "Launcher.h" -#include "dialogs/NewInstanceDialog.h" #include <QFileDialog> #include <QValidator> -#include <InstanceImportTask.h> + +#include "ui/dialogs/NewInstanceDialog.h" + +#include "InstanceImportTask.h" + class UrlValidator : public QValidator { diff --git a/launcher/pages/modplatform/ImportPage.h b/launcher/ui/pages/modplatform/ImportPage.h index cc8a0d1f..aba4def0 100644 --- a/launcher/pages/modplatform/ImportPage.h +++ b/launcher/ui/pages/modplatform/ImportPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("viewfolder"); + return APPLICATION->getThemedIcon("viewfolder"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ImportPage.ui b/launcher/ui/pages/modplatform/ImportPage.ui index eb63cbe9..eb63cbe9 100644 --- a/launcher/pages/modplatform/ImportPage.ui +++ b/launcher/ui/pages/modplatform/ImportPage.ui diff --git a/launcher/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp index 1cf5bbc7..5c58c1f1 100644 --- a/launcher/pages/modplatform/VanillaPage.cpp +++ b/launcher/ui/pages/modplatform/VanillaPage.cpp @@ -1,16 +1,15 @@ #include "VanillaPage.h" #include "ui_VanillaPage.h" -#include "Launcher.h" - -#include <meta/Index.h> -#include <meta/VersionList.h> -#include <dialogs/NewInstanceDialog.h> -#include <Filter.h> -#include <Env.h> -#include <InstanceCreationTask.h> #include <QTabBar> +#include "Application.h" +#include "meta/Index.h" +#include "meta/VersionList.h" +#include "ui/dialogs/NewInstanceDialog.h" +#include "Filter.h" +#include "InstanceCreationTask.h" + VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent) : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage) { @@ -31,7 +30,7 @@ void VanillaPage::openedImpl() { if(!initialized) { - auto vlist = ENV.metadataIndex()->get("net.minecraft"); + auto vlist = APPLICATION->metadataIndex()->get("net.minecraft"); ui->versionList->initialize(vlist.get()); initialized = true; } diff --git a/launcher/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h index e090d8bb..fd4c2daa 100644 --- a/launcher/pages/modplatform/VanillaPage.h +++ b/launcher/ui/pages/modplatform/VanillaPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("minecraft"); + return APPLICATION->getThemedIcon("minecraft"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/VanillaPage.ui index 47effc86..870ff161 100644 --- a/launcher/pages/modplatform/VanillaPage.ui +++ b/launcher/ui/pages/modplatform/VanillaPage.ui @@ -150,7 +150,7 @@ <customwidget> <class>VersionSelectWidget</class> <extends>QWidget</extends> - <header>widgets/VersionSelectWidget.h</header> + <header>ui/widgets/VersionSelectWidget.h</header> <container>1</container> </customwidget> </customwidgets> diff --git a/launcher/pages/modplatform/atlauncher/AtlFilterModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp index b5d8f22b..b5d8f22b 100644 --- a/launcher/pages/modplatform/atlauncher/AtlFilterModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp diff --git a/launcher/pages/modplatform/atlauncher/AtlFilterModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h index bd72ad91..bd72ad91 100644 --- a/launcher/pages/modplatform/atlauncher/AtlFilterModel.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h diff --git a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp index 99d12601..e8c6deee 100644 --- a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp @@ -1,8 +1,7 @@ #include "AtlListModel.h" #include <BuildConfig.h> -#include <Launcher.h> -#include <Env.h> +#include <Application.h> #include <Json.h> namespace Atl { @@ -48,7 +47,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.safeName)); } - auto icon = LAUNCHER->getThemedIcon("atlauncher-placeholder"); + auto icon = APPLICATION->getThemedIcon("atlauncher-placeholder"); auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(pack.safeName.toLower()); ((ListModel *)this)->requestLogo(pack.safeName, url); @@ -75,7 +74,7 @@ void ListModel::request() auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/json/packsnew.json"); netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished); QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed); @@ -134,7 +133,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -167,7 +166,7 @@ void ListModel::requestLogo(QString file, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0))); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0))); NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); @@ -186,7 +185,7 @@ void ListModel::requestLogo(QString file, QString url) emit logoFailed(file); }); - job->start(); + job->start(APPLICATION->network()); m_loadingLogos.append(file); } diff --git a/launcher/pages/modplatform/atlauncher/AtlListModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h index 2d30a64e..79aa8180 100644 --- a/launcher/pages/modplatform/atlauncher/AtlListModel.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h @@ -45,7 +45,7 @@ private: LogoMap m_logoMap; QMap<QString, LogoCallback> waitingCallbacks; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; QByteArray response; }; diff --git a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index 14bbd18b..14bbd18b 100644 --- a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp diff --git a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h index a1df43f6..a1df43f6 100644 --- a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h diff --git a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.ui b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui index 5d3193a4..4c5c2ec5 100644 --- a/launcher/pages/modplatform/atlauncher/AtlOptionalModDialog.ui +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui @@ -57,7 +57,7 @@ <customwidget> <class>ModListView</class> <extends>QTreeView</extends> - <header>widgets/ModListView.h</header> + <header>ui/widgets/ModListView.h</header> </customwidget> </customwidgets> <resources/> diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp index cdf5cc86..5f6a1396 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp @@ -1,11 +1,13 @@ #include "AtlPage.h" #include "ui_AtlPage.h" -#include "dialogs/NewInstanceDialog.h" +#include "modplatform/atlauncher/ATLPackInstallTask.h" + #include "AtlOptionalModDialog.h" -#include <modplatform/atlauncher/ATLPackInstallTask.h> +#include "ui/dialogs/NewInstanceDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" + #include <BuildConfig.h> -#include <dialogs/VersionSelectDialog.h> AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::AtlPage), dialog(dialog) @@ -133,7 +135,7 @@ QVector<QString> AtlPage::chooseOptionalMods(QVector<ATLauncher::VersionMod> mod } QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { - VersionSelectDialog vselect(vlist.get(), "Choose Version", LAUNCHER->activeWindow(), false); + VersionSelectDialog vselect(vlist.get(), "Choose Version", APPLICATION->activeWindow(), false); if (minecraftVersion != Q_NULLPTR) { vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.h b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h index 84c40656..b95b3d9e 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h @@ -21,8 +21,8 @@ #include <QWidget> #include <modplatform/atlauncher/ATLPackInstallTask.h> -#include "Launcher.h" -#include "pages/BasePage.h" +#include "Application.h" +#include "ui/pages/BasePage.h" #include "tasks/Task.h" namespace Ui @@ -45,7 +45,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("atlauncher"); + return APPLICATION->getThemedIcon("atlauncher"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.ui b/launcher/ui/pages/modplatform/atlauncher/AtlPage.ui index 9085766a..9085766a 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.ui +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.ui diff --git a/launcher/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 6dd29d21..a05ab641 100644 --- a/launcher/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -1,5 +1,5 @@ #include "FlameModel.h" -#include "Launcher.h" +#include "Application.h" #include <Json.h> #include <MMCStrings.h> @@ -9,7 +9,6 @@ #include <QLabel> #include <RWStorage.h> -#include <Env.h> namespace Flame { @@ -62,7 +61,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } @@ -100,7 +99,7 @@ void ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); @@ -119,7 +118,7 @@ void ListModel::requestLogo(QString logo, QString url) emit logoFailed(logo); }); - job->start(); + job->start(APPLICATION->network()); m_loadingLogos.append(logo); } @@ -128,7 +127,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(APPLICATION->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -172,7 +171,7 @@ void ListModel::performPaginatedSearch() ).arg(nextSearchOffset).arg(currentSearchTerm).arg(currentSort); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); } diff --git a/launcher/pages/modplatform/flame/FlameModel.h b/launcher/ui/pages/modplatform/flame/FlameModel.h index 24383db0..536f6add 100644 --- a/launcher/pages/modplatform/flame/FlameModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModel.h @@ -69,7 +69,7 @@ private: ResetRequested, Finished } searchState = None; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; QByteArray response; }; diff --git a/launcher/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 8f798df6..cb1185f7 100644 --- a/launcher/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -1,13 +1,14 @@ #include "FlamePage.h" #include "ui_FlamePage.h" -#include "Launcher.h" -#include <Json.h> -#include "dialogs/NewInstanceDialog.h" -#include <InstanceImportTask.h> -#include "FlameModel.h" #include <QKeyEvent> +#include "Application.h" +#include "Json.h" +#include "ui/dialogs/NewInstanceDialog.h" +#include "InstanceImportTask.h" +#include "FlameModel.h" + FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) { @@ -112,7 +113,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second) std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>(); int addonId = current.addonId; netJob->addNetAction(Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response.get())); - + QObject::connect(netJob, &NetJob::succeeded, this, [this, response] { QJsonParseError parse_error; @@ -139,7 +140,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second) suggestCurrent(); }); - netJob->start(); + netJob->start(APPLICATION->network()); } else { diff --git a/launcher/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index c3d2630a..5cfe21dc 100644 --- a/launcher/pages/modplatform/flame/FlamePage.h +++ b/launcher/ui/pages/modplatform/flame/FlamePage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" #include <modplatform/flame/FlamePackIndex.h> @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("flame"); + return APPLICATION->getThemedIcon("flame"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui index 9723815a..9723815a 100644 --- a/launcher/pages/modplatform/flame/FlamePage.ui +++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui diff --git a/launcher/pages/modplatform/ftb/FtbFilterModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp index 793b8769..793b8769 100644 --- a/launcher/pages/modplatform/ftb/FtbFilterModel.cpp +++ b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp diff --git a/launcher/pages/modplatform/ftb/FtbFilterModel.h b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h index 2e712c7d..2e712c7d 100644 --- a/launcher/pages/modplatform/ftb/FtbFilterModel.h +++ b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h diff --git a/launcher/pages/modplatform/ftb/FtbListModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp index c4c2c83e..59cd0b85 100644 --- a/launcher/pages/modplatform/ftb/FtbListModel.cpp +++ b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp @@ -1,8 +1,7 @@ #include "FtbListModel.h" #include "BuildConfig.h" -#include "Env.h" -#include "Launcher.h" +#include "Application.h" #include "Json.h" #include <QPainter> @@ -46,7 +45,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const } else if(role == Qt::DecorationRole) { - QIcon placeholder = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon placeholder = APPLICATION->getThemedIcon("screenshot-placeholder"); auto iter = m_logoMap.find(pack.name); if (iter != m_logoMap.end()) { @@ -78,7 +77,7 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(APPLICATION->metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { @@ -96,7 +95,7 @@ void ListModel::request() auto url = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all"); netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished); QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed); @@ -140,7 +139,7 @@ void ListModel::requestPack() .arg(currentPack); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished); QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed); @@ -252,7 +251,7 @@ void ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); bool stale = entry->isStale(); @@ -273,7 +272,7 @@ void ListModel::requestLogo(QString logo, QString url) auto &newLogoEntry = m_logoMap[logo]; newLogoEntry.downloadJob = job; newLogoEntry.fullpath = fullPath; - job->start(); + job->start(APPLICATION->network()); } } diff --git a/launcher/pages/modplatform/ftb/FtbListModel.h b/launcher/ui/pages/modplatform/ftb/FtbListModel.h index 2d6e91da..e2b73c25 100644 --- a/launcher/pages/modplatform/ftb/FtbListModel.h +++ b/launcher/ui/pages/modplatform/ftb/FtbListModel.h @@ -10,7 +10,7 @@ namespace Ftb { struct Logo { QString fullpath; - NetJobPtr downloadJob; + NetJob::Ptr downloadJob; QIcon result; bool failed = false; }; @@ -52,7 +52,7 @@ private: QList<ModpacksCH::Modpack> modpacks; LogoMap m_logoMap; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; int currentPack; QList<int> remainingPacks; QByteArray response; diff --git a/launcher/pages/modplatform/ftb/FtbPage.cpp b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp index 620a56d8..a82de1d6 100644 --- a/launcher/pages/modplatform/ftb/FtbPage.cpp +++ b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp @@ -3,7 +3,7 @@ #include <QKeyEvent> -#include "dialogs/NewInstanceDialog.h" +#include "ui/dialogs/NewInstanceDialog.h" #include "modplatform/modpacksch/FTBPackInstallTask.h" #include "HoeDown.h" diff --git a/launcher/pages/modplatform/ftb/FtbPage.h b/launcher/ui/pages/modplatform/ftb/FtbPage.h index 0a4a6cea..28a189f0 100644 --- a/launcher/pages/modplatform/ftb/FtbPage.h +++ b/launcher/ui/pages/modplatform/ftb/FtbPage.h @@ -20,8 +20,8 @@ #include <QWidget> -#include "Launcher.h" -#include "pages/BasePage.h" +#include "Application.h" +#include "ui/pages/BasePage.h" #include "tasks/Task.h" namespace Ui @@ -44,7 +44,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("ftb_logo"); + return APPLICATION->getThemedIcon("ftb_logo"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ftb/FtbPage.ui b/launcher/ui/pages/modplatform/ftb/FtbPage.ui index e9c783e3..e9c783e3 100644 --- a/launcher/pages/modplatform/ftb/FtbPage.ui +++ b/launcher/ui/pages/modplatform/ftb/FtbPage.ui diff --git a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 78063c5f..5fa932b7 100644 --- a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -1,5 +1,5 @@ #include "ListModel.h" -#include "Launcher.h" +#include "Application.h" #include <MMCStrings.h> #include <Version.h> @@ -8,7 +8,6 @@ #include <QLabel> #include <RWStorage.h> -#include <Env.h> #include <BuildConfig.h> @@ -130,7 +129,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logo)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logo); return icon; } @@ -216,7 +215,7 @@ void ListModel::requestLogo(QString file) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0))); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0))); NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file)); job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry)); @@ -235,7 +234,7 @@ void ListModel::requestLogo(QString file) emit logoFailed(file); }); - job->start(); + job->start(APPLICATION->network()); m_loadingLogos.append(file); } @@ -244,7 +243,7 @@ void ListModel::getLogo(const QString &logo, LogoCallback callback) { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); } else { diff --git a/launcher/pages/modplatform/legacy_ftb/ListModel.h b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h index c55df000..c55df000 100644 --- a/launcher/pages/modplatform/legacy_ftb/ListModel.h +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.h diff --git a/launcher/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp index 6b6a7dcd..891704de 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp @@ -3,9 +3,11 @@ #include <QInputDialog> -#include "Launcher.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/NewInstanceDialog.h" +#include "Application.h" + +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/NewInstanceDialog.h" + #include "modplatform/legacy_ftb/PackFetchTask.h" #include "modplatform/legacy_ftb/PackInstallTask.h" #include "modplatform/legacy_ftb/PrivatePackManager.h" @@ -16,7 +18,7 @@ namespace LegacyFTB { Page::Page(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), dialog(dialog), ui(new Ui::Page) { - ftbFetchTask.reset(new PackFetchTask()); + ftbFetchTask.reset(new PackFetchTask(APPLICATION->network())); ftbPrivatePacks.reset(new PrivatePackManager()); ui->setupUi(this); @@ -133,7 +135,7 @@ void Page::suggestCurrent() return; } - dialog->setSuggestedPack(selected.name, new PackInstallTask(selected, selectedVersion)); + dialog->setSuggestedPack(selected.name, new PackInstallTask(APPLICATION->network(), selected, selectedVersion)); QString editedLogoName; if(selected.logo.toLower().startsWith("ftb")) { diff --git a/launcher/pages/modplatform/legacy_ftb/Page.h b/launcher/ui/pages/modplatform/legacy_ftb/Page.h index 6159cd9d..d8225e11 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.h +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.h @@ -19,8 +19,8 @@ #include <QTreeView> #include <QTextBrowser> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" #include "modplatform/legacy_ftb/PackHelpers.h" #include "modplatform/legacy_ftb/PackFetchTask.h" @@ -54,7 +54,7 @@ public: } QIcon icon() const override { - return LAUNCHER->getThemedIcon("ftb_logo"); + return APPLICATION->getThemedIcon("ftb_logo"); } QString id() const override { diff --git a/launcher/pages/modplatform/legacy_ftb/Page.ui b/launcher/ui/pages/modplatform/legacy_ftb/Page.ui index 15e5d432..15e5d432 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.ui +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.ui diff --git a/launcher/pages/modplatform/technic/TechnicData.h b/launcher/ui/pages/modplatform/technic/TechnicData.h index 50fd75e8..50fd75e8 100644 --- a/launcher/pages/modplatform/technic/TechnicData.h +++ b/launcher/ui/pages/modplatform/technic/TechnicData.h diff --git a/launcher/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp index cac6fef1..63c2d4c4 100644 --- a/launcher/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp @@ -14,8 +14,7 @@ */ #include "TechnicModel.h" -#include "Env.h" -#include "Launcher.h" +#include "Application.h" #include "Json.h" #include <QIcon> @@ -47,7 +46,7 @@ QVariant Technic::ListModel::data(const QModelIndex& index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } @@ -105,7 +104,7 @@ void Technic::ListModel::performSearch() } netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; - jobPtr->start(); + jobPtr->start(APPLICATION->network()); QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); } @@ -163,7 +162,7 @@ void Technic::ListModel::getLogo(const QString& logo, const QString& logoUrl, Te { if(m_logoMap.contains(logo)) { - callback(ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath()); + callback(APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath()); } else { @@ -216,7 +215,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url) return; } - MetaEntryPtr entry = ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo)); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); @@ -232,7 +231,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url) logoFailed(logo); }); - job->start(); + job->start(APPLICATION->network()); m_loadingLogos.append(logo); } diff --git a/launcher/pages/modplatform/technic/TechnicModel.h b/launcher/ui/pages/modplatform/technic/TechnicModel.h index 82a03842..e80e6e7c 100644 --- a/launcher/pages/modplatform/technic/TechnicModel.h +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.h @@ -63,7 +63,7 @@ private: ResetRequested, Finished } searchState = None; - NetJobPtr jobPtr; + NetJob::Ptr jobPtr; QByteArray response; }; diff --git a/launcher/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp index 4f27e685..ac69675c 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp @@ -16,14 +16,17 @@ #include "TechnicPage.h" #include "ui_TechnicPage.h" -#include "Launcher.h" -#include "dialogs/NewInstanceDialog.h" -#include "TechnicModel.h" #include <QKeyEvent> + +#include "ui/dialogs/NewInstanceDialog.h" + +#include "TechnicModel.h" #include "modplatform/technic/SingleZipPackInstallTask.h" #include "modplatform/technic/SolderPackInstallTask.h" #include "Json.h" +#include "Application.h" + TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog) { @@ -164,7 +167,7 @@ void TechnicPage::suggestCurrent() current.metadataLoaded = true; metadataLoaded(); }); - netJob->start(); + netJob->start(APPLICATION->network()); } // expects current.metadataLoaded to be true @@ -193,6 +196,6 @@ void TechnicPage::metadataLoaded() else { while (current.url.endsWith('/')) current.url.chop(1); - dialog->setSuggestedPack(current.name, new Technic::SolderPackInstallTask(current.url + "/modpack/" + current.slug, current.minecraftVersion)); + dialog->setSuggestedPack(current.name, new Technic::SolderPackInstallTask(APPLICATION->network(), current.url + "/modpack/" + current.slug, current.minecraftVersion)); } } diff --git a/launcher/pages/modplatform/technic/TechnicPage.h b/launcher/ui/pages/modplatform/technic/TechnicPage.h index f0619a52..21695dd0 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.h +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.h @@ -17,8 +17,8 @@ #include <QWidget> -#include "pages/BasePage.h" -#include <Launcher.h> +#include "ui/pages/BasePage.h" +#include <Application.h> #include "tasks/Task.h" #include "TechnicData.h" @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return LAUNCHER->getThemedIcon("technic"); + return APPLICATION->getThemedIcon("technic"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/technic/TechnicPage.ui b/launcher/ui/pages/modplatform/technic/TechnicPage.ui index 2ca45dd2..dde685d9 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.ui +++ b/launcher/ui/pages/modplatform/technic/TechnicPage.ui @@ -81,7 +81,7 @@ <customwidget> <class>MCModInfoFrame</class> <extends>QFrame</extends> - <header>widgets/MCModInfoFrame.h</header> + <header>ui/widgets/MCModInfoFrame.h</header> <container>1</container> </customwidget> </customwidgets> diff --git a/launcher/setupwizard/AnalyticsWizardPage.cpp b/launcher/ui/setupwizard/AnalyticsWizardPage.cpp index f1d7b006..3db2f6dc 100644 --- a/launcher/setupwizard/AnalyticsWizardPage.cpp +++ b/launcher/ui/setupwizard/AnalyticsWizardPage.cpp @@ -1,5 +1,5 @@ #include "AnalyticsWizardPage.h" -#include <Launcher.h> +#include <Application.h> #include <QVBoxLayout> #include <QTextBrowser> @@ -33,8 +33,8 @@ AnalyticsWizardPage::~AnalyticsWizardPage() bool AnalyticsWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); - auto analytics = LAUNCHER->analytics(); + auto settings = APPLICATION->settings(); + auto analytics = APPLICATION->analytics(); auto status = checkBox->isChecked(); settings->set("AnalyticsSeen", analytics->version()); settings->set("Analytics", status); diff --git a/launcher/setupwizard/AnalyticsWizardPage.h b/launcher/ui/setupwizard/AnalyticsWizardPage.h index c451db2c..c451db2c 100644 --- a/launcher/setupwizard/AnalyticsWizardPage.h +++ b/launcher/ui/setupwizard/AnalyticsWizardPage.h diff --git a/launcher/setupwizard/BaseWizardPage.h b/launcher/ui/setupwizard/BaseWizardPage.h index 72dbecfd..72dbecfd 100644 --- a/launcher/setupwizard/BaseWizardPage.h +++ b/launcher/ui/setupwizard/BaseWizardPage.h diff --git a/launcher/setupwizard/JavaWizardPage.cpp b/launcher/ui/setupwizard/JavaWizardPage.cpp index a60090ce..63b3d480 100644 --- a/launcher/setupwizard/JavaWizardPage.cpp +++ b/launcher/ui/setupwizard/JavaWizardPage.cpp @@ -1,5 +1,5 @@ #include "JavaWizardPage.h" -#include <Launcher.h> +#include "Application.h" #include <QVBoxLayout> #include <QGroupBox> @@ -8,16 +8,18 @@ #include <QLineEdit> #include <QPushButton> #include <QToolButton> -#include <widgets/VersionSelectWidget.h> -#include <FileSystem.h> +#include <QFileDialog> -#include <java/JavaInstall.h> -#include <dialogs/CustomMessageBox.h> -#include <java/JavaUtils.h> #include <sys.h> -#include <QFileDialog> -#include <JavaCommon.h> -#include "widgets/JavaSettingsWidget.h" + +#include "FileSystem.h" +#include "java/JavaInstall.h" +#include "java/JavaUtils.h" +#include "JavaCommon.h" + +#include "ui/widgets/VersionSelectWidget.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/widgets/JavaSettingsWidget.h" JavaWizardPage::JavaWizardPage(QWidget *parent) @@ -55,7 +57,7 @@ bool JavaWizardPage::wantsRefreshButton() bool JavaWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); auto result = m_java_widget->validate(); switch(result) { @@ -71,7 +73,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::JavaBad: { // Memory - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); s->set("MinMemAlloc", m_java_widget->minHeapSize()); s->set("MaxMemAlloc", m_java_widget->maxHeapSize()); if (m_java_widget->permGenEnabled()) diff --git a/launcher/setupwizard/JavaWizardPage.h b/launcher/ui/setupwizard/JavaWizardPage.h index 0d749039..0d749039 100644 --- a/launcher/setupwizard/JavaWizardPage.h +++ b/launcher/ui/setupwizard/JavaWizardPage.h diff --git a/launcher/setupwizard/LanguageWizardPage.cpp b/launcher/ui/setupwizard/LanguageWizardPage.cpp index e352ccca..072df10d 100644 --- a/launcher/setupwizard/LanguageWizardPage.cpp +++ b/launcher/ui/setupwizard/LanguageWizardPage.cpp @@ -1,8 +1,8 @@ #include "LanguageWizardPage.h" -#include <Launcher.h> +#include <Application.h> #include <translations/TranslationsModel.h> -#include "widgets/LanguageSelectionWidget.h" +#include "ui/widgets/LanguageSelectionWidget.h" #include <QVBoxLayout> #include <BuildConfig.h> @@ -29,13 +29,13 @@ bool LanguageWizardPage::wantsRefreshButton() void LanguageWizardPage::refresh() { - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); translations->downloadIndex(); } bool LanguageWizardPage::validatePage() { - auto settings = LAUNCHER->settings(); + auto settings = APPLICATION->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); return true; diff --git a/launcher/setupwizard/LanguageWizardPage.h b/launcher/ui/setupwizard/LanguageWizardPage.h index 45a0e5c0..45a0e5c0 100644 --- a/launcher/setupwizard/LanguageWizardPage.h +++ b/launcher/ui/setupwizard/LanguageWizardPage.h diff --git a/launcher/setupwizard/SetupWizard.cpp b/launcher/ui/setupwizard/SetupWizard.cpp index 46b2ef79..5af5ba91 100644 --- a/launcher/setupwizard/SetupWizard.cpp +++ b/launcher/ui/setupwizard/SetupWizard.cpp @@ -5,7 +5,7 @@ #include "AnalyticsWizardPage.h" #include "translations/TranslationsModel.h" -#include <Launcher.h> +#include <Application.h> #include <FileSystem.h> #include <ganalytics.h> diff --git a/launcher/setupwizard/SetupWizard.h b/launcher/ui/setupwizard/SetupWizard.h index 9b8adb4d..9b8adb4d 100644 --- a/launcher/setupwizard/SetupWizard.h +++ b/launcher/ui/setupwizard/SetupWizard.h diff --git a/launcher/themes/BrightTheme.cpp b/launcher/ui/themes/BrightTheme.cpp index b9188bdd..b9188bdd 100644 --- a/launcher/themes/BrightTheme.cpp +++ b/launcher/ui/themes/BrightTheme.cpp diff --git a/launcher/themes/BrightTheme.h b/launcher/ui/themes/BrightTheme.h index c61f52d5..c61f52d5 100644 --- a/launcher/themes/BrightTheme.h +++ b/launcher/ui/themes/BrightTheme.h diff --git a/launcher/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 3e3e27de..3e3e27de 100644 --- a/launcher/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp diff --git a/launcher/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index d216895d..d216895d 100644 --- a/launcher/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h diff --git a/launcher/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp index 31ecd559..31ecd559 100644 --- a/launcher/themes/DarkTheme.cpp +++ b/launcher/ui/themes/DarkTheme.cpp diff --git a/launcher/themes/DarkTheme.h b/launcher/ui/themes/DarkTheme.h index 9bd2f343..9bd2f343 100644 --- a/launcher/themes/DarkTheme.h +++ b/launcher/ui/themes/DarkTheme.h diff --git a/launcher/themes/FusionTheme.cpp b/launcher/ui/themes/FusionTheme.cpp index cf3286ba..cf3286ba 100644 --- a/launcher/themes/FusionTheme.cpp +++ b/launcher/ui/themes/FusionTheme.cpp diff --git a/launcher/themes/FusionTheme.h b/launcher/ui/themes/FusionTheme.h index ee34245a..ee34245a 100644 --- a/launcher/themes/FusionTheme.h +++ b/launcher/ui/themes/FusionTheme.h diff --git a/launcher/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp index 321b0d9b..7247b444 100644 --- a/launcher/themes/ITheme.cpp +++ b/launcher/ui/themes/ITheme.cpp @@ -2,7 +2,7 @@ #include "rainbow.h" #include <QStyleFactory> #include <QDir> -#include "Launcher.h" +#include "Application.h" void ITheme::apply(bool) { @@ -13,11 +13,11 @@ void ITheme::apply(bool) } if(hasStyleSheet()) { - LAUNCHER->setStyleSheet(appStyleSheet()); + APPLICATION->setStyleSheet(appStyleSheet()); } else { - LAUNCHER->setStyleSheet(QString()); + APPLICATION->setStyleSheet(QString()); } QDir::setSearchPaths("theme", searchPaths()); } diff --git a/launcher/themes/ITheme.h b/launcher/ui/themes/ITheme.h index c2347cf6..c2347cf6 100644 --- a/launcher/themes/ITheme.h +++ b/launcher/ui/themes/ITheme.h diff --git a/launcher/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 49b1afaa..49b1afaa 100644 --- a/launcher/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp diff --git a/launcher/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h index fe450600..fe450600 100644 --- a/launcher/themes/SystemTheme.h +++ b/launcher/ui/themes/SystemTheme.h diff --git a/launcher/widgets/Common.cpp b/launcher/ui/widgets/Common.cpp index f72f3596..f72f3596 100644 --- a/launcher/widgets/Common.cpp +++ b/launcher/ui/widgets/Common.cpp diff --git a/launcher/widgets/Common.h b/launcher/ui/widgets/Common.h index b3fbe1a0..b3fbe1a0 100644 --- a/launcher/widgets/Common.h +++ b/launcher/ui/widgets/Common.h diff --git a/launcher/widgets/CustomCommands.cpp b/launcher/ui/widgets/CustomCommands.cpp index 24bdc07d..24bdc07d 100644 --- a/launcher/widgets/CustomCommands.cpp +++ b/launcher/ui/widgets/CustomCommands.cpp diff --git a/launcher/widgets/CustomCommands.h b/launcher/ui/widgets/CustomCommands.h index 8db991fa..8db991fa 100644 --- a/launcher/widgets/CustomCommands.h +++ b/launcher/ui/widgets/CustomCommands.h diff --git a/launcher/widgets/CustomCommands.ui b/launcher/ui/widgets/CustomCommands.ui index 21964ad2..21964ad2 100644 --- a/launcher/widgets/CustomCommands.ui +++ b/launcher/ui/widgets/CustomCommands.ui diff --git a/launcher/widgets/DropLabel.cpp b/launcher/ui/widgets/DropLabel.cpp index a900e57c..a900e57c 100644 --- a/launcher/widgets/DropLabel.cpp +++ b/launcher/ui/widgets/DropLabel.cpp diff --git a/launcher/widgets/DropLabel.h b/launcher/ui/widgets/DropLabel.h index c5ca0bcc..c5ca0bcc 100644 --- a/launcher/widgets/DropLabel.h +++ b/launcher/ui/widgets/DropLabel.h diff --git a/launcher/widgets/FocusLineEdit.cpp b/launcher/ui/widgets/FocusLineEdit.cpp index b272100c..b272100c 100644 --- a/launcher/widgets/FocusLineEdit.cpp +++ b/launcher/ui/widgets/FocusLineEdit.cpp diff --git a/launcher/widgets/FocusLineEdit.h b/launcher/ui/widgets/FocusLineEdit.h index 71b4f140..71b4f140 100644 --- a/launcher/widgets/FocusLineEdit.h +++ b/launcher/ui/widgets/FocusLineEdit.h diff --git a/launcher/widgets/IconLabel.cpp b/launcher/ui/widgets/IconLabel.cpp index bf1c2358..bf1c2358 100644 --- a/launcher/widgets/IconLabel.cpp +++ b/launcher/ui/widgets/IconLabel.cpp diff --git a/launcher/widgets/IconLabel.h b/launcher/ui/widgets/IconLabel.h index 6d212c4c..6d212c4c 100644 --- a/launcher/widgets/IconLabel.h +++ b/launcher/ui/widgets/IconLabel.h diff --git a/launcher/widgets/InstanceCardWidget.ui b/launcher/ui/widgets/InstanceCardWidget.ui index 6eeeb076..6eeeb076 100644 --- a/launcher/widgets/InstanceCardWidget.ui +++ b/launcher/ui/widgets/InstanceCardWidget.ui diff --git a/launcher/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index 11f0653a..b9d7620c 100644 --- a/launcher/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -1,10 +1,4 @@ #include "JavaSettingsWidget.h" -#include <Launcher.h> - -#include <java/JavaInstall.h> -#include <dialogs/CustomMessageBox.h> -#include <java/JavaUtils.h> -#include <sys.h> #include <QVBoxLayout> #include <QGroupBox> @@ -13,18 +7,27 @@ #include <QLineEdit> #include <QPushButton> #include <QToolButton> -#include <widgets/VersionSelectWidget.h> -#include <FileSystem.h> #include <QFileDialog> -#include <BuildConfig.h> + +#include <sys.h> + +#include "java/JavaInstall.h" +#include "java/JavaUtils.h" +#include "FileSystem.h" + +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/widgets/VersionSelectWidget.h" + +#include "Application.h" +#include "BuildConfig.h" JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) { m_availableMemory = Sys::getSystemRam() / Sys::mebibyte; - goodIcon = LAUNCHER->getThemedIcon("status-good"); - yellowIcon = LAUNCHER->getThemedIcon("status-yellow"); - badIcon = LAUNCHER->getThemedIcon("status-bad"); + goodIcon = APPLICATION->getThemedIcon("status-good"); + yellowIcon = APPLICATION->getThemedIcon("status-yellow"); + badIcon = APPLICATION->getThemedIcon("status-bad"); setupUi(); connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); @@ -116,9 +119,9 @@ void JavaSettingsWidget::setupUi() void JavaSettingsWidget::initialize() { - m_versionWidget->initialize(LAUNCHER->javalist().get()); + m_versionWidget->initialize(APPLICATION->javalist().get()); m_versionWidget->setResizeOn(2); - auto s = LAUNCHER->settings(); + auto s = APPLICATION->settings(); // Memory observedMinMemory = s->get("MinMemAlloc").toInt(); observedMaxMemory = s->get("MaxMemAlloc").toInt(); diff --git a/launcher/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h index 0d280daf..0d280daf 100644 --- a/launcher/widgets/JavaSettingsWidget.h +++ b/launcher/ui/widgets/JavaSettingsWidget.h diff --git a/launcher/widgets/LabeledToolButton.cpp b/launcher/ui/widgets/LabeledToolButton.cpp index ab2d3278..ab2d3278 100644 --- a/launcher/widgets/LabeledToolButton.cpp +++ b/launcher/ui/widgets/LabeledToolButton.cpp diff --git a/launcher/widgets/LabeledToolButton.h b/launcher/ui/widgets/LabeledToolButton.h index 51f99e9b..51f99e9b 100644 --- a/launcher/widgets/LabeledToolButton.h +++ b/launcher/ui/widgets/LabeledToolButton.h diff --git a/launcher/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp index 2b972ba7..cf70c7b4 100644 --- a/launcher/widgets/LanguageSelectionWidget.cpp +++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp @@ -4,7 +4,7 @@ #include <QTreeView> #include <QHeaderView> #include <QLabel> -#include "Launcher.h" +#include "Application.h" #include "translations/TranslationsModel.h" LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : @@ -29,7 +29,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : helpUsLabel->setWordWrap(true); verticalLayout->addWidget(helpUsLabel); - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); auto index = translations->selectedIndex(); languageView->setModel(translations.get()); languageView->setCurrentIndex(index); @@ -41,7 +41,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) : QString LanguageSelectionWidget::getSelectedLanguageKey() const { - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); return translations->data(languageView->currentIndex(), Qt::UserRole).toString(); } @@ -59,7 +59,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con { return; } - auto translations = LAUNCHER->translations(); + auto translations = APPLICATION->translations(); QString key = translations->data(current, Qt::UserRole).toString(); translations->selectLanguage(key); translations->updateLanguage(key); diff --git a/launcher/widgets/LanguageSelectionWidget.h b/launcher/ui/widgets/LanguageSelectionWidget.h index e65936db..e65936db 100644 --- a/launcher/widgets/LanguageSelectionWidget.h +++ b/launcher/ui/widgets/LanguageSelectionWidget.h diff --git a/launcher/widgets/LineSeparator.cpp b/launcher/ui/widgets/LineSeparator.cpp index d03e6762..d03e6762 100644 --- a/launcher/widgets/LineSeparator.cpp +++ b/launcher/ui/widgets/LineSeparator.cpp diff --git a/launcher/widgets/LineSeparator.h b/launcher/ui/widgets/LineSeparator.h index 22927b68..22927b68 100644 --- a/launcher/widgets/LineSeparator.h +++ b/launcher/ui/widgets/LineSeparator.h diff --git a/launcher/widgets/LogView.cpp b/launcher/ui/widgets/LogView.cpp index 26a2a527..26a2a527 100644 --- a/launcher/widgets/LogView.cpp +++ b/launcher/ui/widgets/LogView.cpp diff --git a/launcher/widgets/LogView.h b/launcher/ui/widgets/LogView.h index 3143360a..3143360a 100644 --- a/launcher/widgets/LogView.h +++ b/launcher/ui/widgets/LogView.h diff --git a/launcher/widgets/MCModInfoFrame.cpp b/launcher/ui/widgets/MCModInfoFrame.cpp index 5b1f6230..8c4bd690 100644 --- a/launcher/widgets/MCModInfoFrame.cpp +++ b/launcher/ui/widgets/MCModInfoFrame.cpp @@ -18,7 +18,8 @@ #include "MCModInfoFrame.h" #include "ui_MCModInfoFrame.h" -#include "dialogs/CustomMessageBox.h" + +#include "ui/dialogs/CustomMessageBox.h" void MCModInfoFrame::updateWithMod(Mod &m) { diff --git a/launcher/widgets/MCModInfoFrame.h b/launcher/ui/widgets/MCModInfoFrame.h index 0b7ef537..0b7ef537 100644 --- a/launcher/widgets/MCModInfoFrame.h +++ b/launcher/ui/widgets/MCModInfoFrame.h diff --git a/launcher/widgets/MCModInfoFrame.ui b/launcher/ui/widgets/MCModInfoFrame.ui index 5ef33379..5ef33379 100644 --- a/launcher/widgets/MCModInfoFrame.ui +++ b/launcher/ui/widgets/MCModInfoFrame.ui diff --git a/launcher/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index c8ccd292..c8ccd292 100644 --- a/launcher/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp diff --git a/launcher/widgets/ModListView.h b/launcher/ui/widgets/ModListView.h index 881e092f..881e092f 100644 --- a/launcher/widgets/ModListView.h +++ b/launcher/ui/widgets/ModListView.h diff --git a/launcher/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 25e3b676..74a6dff3 100644 --- a/launcher/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -14,6 +14,7 @@ */ #include "PageContainer.h" +#include "PageContainer_p.h" #include <QStackedLayout> #include <QPushButton> @@ -26,12 +27,12 @@ #include <QDialogButtonBox> #include <QGridLayout> -#include "Launcher.h" #include "settings/SettingsObject.h" -#include "widgets/IconLabel.h" -#include "PageContainer_p.h" -#include <Launcher.h> -#include <DesktopServices.h> + +#include "ui/widgets/IconLabel.h" + +#include "DesktopServices.h" +#include "Application.h" class PageEntryFilterModel : public QSortFilterProxyModel { @@ -139,12 +140,12 @@ void PageContainer::createUI() m_header->setFont(headerLabelFont); QHBoxLayout *headerHLayout = new QHBoxLayout; - const int leftMargin = LAUNCHER->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + const int leftMargin = APPLICATION->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->addWidget(m_header); headerHLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); headerHLayout->addWidget(m_iconHeader); - const int rightMargin = LAUNCHER->style()->pixelMetric(QStyle::PM_LayoutRightMargin); + const int rightMargin = APPLICATION->style()->pixelMetric(QStyle::PM_LayoutRightMargin); headerHLayout->addSpacerItem(new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->setContentsMargins(0, 6, 0, 0); @@ -195,7 +196,7 @@ void PageContainer::showPage(int row) { m_pageStack->setCurrentIndex(0); m_header->setText(QString()); - m_iconHeader->setIcon(LAUNCHER->getThemedIcon("bug")); + m_iconHeader->setIcon(APPLICATION->getThemedIcon("bug")); } } diff --git a/launcher/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index 976d34e9..8d2172db 100644 --- a/launcher/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -18,8 +18,8 @@ #include <QWidget> #include <QModelIndex> -#include "pages/BasePageProvider.h" -#include "pages/BasePageContainer.h" +#include "ui/pages/BasePageProvider.h" +#include "ui/pages/BasePageContainer.h" class QLayout; class IconLabel; diff --git a/launcher/widgets/PageContainer_p.h b/launcher/ui/widgets/PageContainer_p.h index da1a66f4..da1a66f4 100644 --- a/launcher/widgets/PageContainer_p.h +++ b/launcher/ui/widgets/PageContainer_p.h diff --git a/launcher/widgets/ProgressWidget.cpp b/launcher/ui/widgets/ProgressWidget.cpp index 911e555d..911e555d 100644 --- a/launcher/widgets/ProgressWidget.cpp +++ b/launcher/ui/widgets/ProgressWidget.cpp diff --git a/launcher/widgets/ProgressWidget.h b/launcher/ui/widgets/ProgressWidget.h index fa67748a..fa67748a 100644 --- a/launcher/widgets/ProgressWidget.h +++ b/launcher/ui/widgets/ProgressWidget.h diff --git a/launcher/widgets/VersionListView.cpp b/launcher/ui/widgets/VersionListView.cpp index 8424fedd..aba0b1a1 100644 --- a/launcher/widgets/VersionListView.cpp +++ b/launcher/ui/widgets/VersionListView.cpp @@ -19,7 +19,6 @@ #include <QDrag> #include <QPainter> #include "VersionListView.h" -#include "Common.h" VersionListView::VersionListView(QWidget *parent) :QTreeView ( parent ) diff --git a/launcher/widgets/VersionListView.h b/launcher/ui/widgets/VersionListView.h index 4153b314..4153b314 100644 --- a/launcher/widgets/VersionListView.h +++ b/launcher/ui/widgets/VersionListView.h diff --git a/launcher/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp index 9925a6b4..1209f118 100644 --- a/launcher/widgets/VersionSelectWidget.cpp +++ b/launcher/ui/widgets/VersionSelectWidget.cpp @@ -1,10 +1,13 @@ #include "VersionSelectWidget.h" + #include <QProgressBar> #include <QVBoxLayout> -#include "VersionListView.h" #include <QHeaderView> -#include <VersionProxyModel.h> -#include <dialogs/CustomMessageBox.h> + +#include "VersionListView.h" +#include "VersionProxyModel.h" + +#include "ui/dialogs/CustomMessageBox.h" VersionSelectWidget::VersionSelectWidget(QWidget* parent) : QWidget(parent) diff --git a/launcher/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h index 0a649408..0a649408 100644 --- a/launcher/widgets/VersionSelectWidget.h +++ b/launcher/ui/widgets/VersionSelectWidget.h diff --git a/launcher/widgets/WideBar.cpp b/launcher/ui/widgets/WideBar.cpp index cbd6c617..cbd6c617 100644 --- a/launcher/widgets/WideBar.cpp +++ b/launcher/ui/widgets/WideBar.cpp diff --git a/launcher/widgets/WideBar.h b/launcher/ui/widgets/WideBar.h index d1b8cbe7..d1b8cbe7 100644 --- a/launcher/widgets/WideBar.h +++ b/launcher/ui/widgets/WideBar.h diff --git a/launcher/updater/DownloadTask.cpp b/launcher/updater/DownloadTask.cpp index 875d9d84..eba59142 100644 --- a/launcher/updater/DownloadTask.cpp +++ b/launcher/updater/DownloadTask.cpp @@ -26,8 +26,12 @@ namespace GoUpdate { -DownloadTask::DownloadTask(Status status, QString target, QObject *parent) - : Task(parent), m_updateFilesDir(target) +DownloadTask::DownloadTask( + shared_qobject_ptr<QNetworkAccessManager> network, + Status status, + QString target, + QObject *parent +) : Task(parent), m_updateFilesDir(target), m_network(network) { m_status = status; @@ -63,7 +67,7 @@ void DownloadTask::loadVersionInfo() connect(netJob, &NetJob::succeeded, this, &DownloadTask::processDownloadedVersionInfo); connect(netJob, &NetJob::failed, this, &DownloadTask::vinfoDownloadFailed); m_vinfoNetJob.reset(netJob); - netJob->start(); + netJob->start(m_network); } void DownloadTask::vinfoDownloadFailed() @@ -117,7 +121,7 @@ void DownloadTask::processDownloadedVersionInfo() setStatus(tr("Processing file lists - figuring out how to install the update...")); // make a new netjob for the actual update files - NetJobPtr netJob (new NetJob("Update Files")); + NetJob::Ptr netJob (new NetJob("Update Files")); // fill netJob and operationList if (!processFileLists(m_currentVersionFileList, m_newVersionFileList, m_status.rootPath, m_updateFilesDir.path(), netJob, m_operations)) @@ -141,7 +145,7 @@ void DownloadTask::processDownloadedVersionInfo() } qDebug() << "Begin downloading update files to" << m_updateFilesDir.path(); m_filesNetJob = netJob; - m_filesNetJob->start(); + m_filesNetJob->start(m_network); } void DownloadTask::fileDownloadFinished() diff --git a/launcher/updater/DownloadTask.h b/launcher/updater/DownloadTask.h index fc5030b4..eac26238 100644 --- a/launcher/updater/DownloadTask.h +++ b/launcher/updater/DownloadTask.h @@ -35,7 +35,7 @@ public: * * target is a template - XXXXXX at the end will be replaced with a random generated string, ensuring uniqueness */ - explicit DownloadTask(Status status, QString target, QObject* parent = 0); + explicit DownloadTask(shared_qobject_ptr<QNetworkAccessManager> network, Status status, QString target, QObject* parent = 0); virtual ~DownloadTask() {}; /// Get the directory that will contain the update files. @@ -62,13 +62,13 @@ protected: */ void loadVersionInfo(); - NetJobPtr m_vinfoNetJob; + NetJob::Ptr m_vinfoNetJob; QByteArray currentVersionFileListData; QByteArray newVersionFileListData; Net::Download::Ptr m_currentVersionFileListDownload; Net::Download::Ptr m_newVersionFileListDownload; - NetJobPtr m_filesNetJob; + NetJob::Ptr m_filesNetJob; Status m_status; @@ -91,6 +91,9 @@ protected slots: void fileDownloadFinished(); void fileDownloadFailed(QString reason); void fileDownloadProgressChanged(qint64 current, qint64 total); + +private: + shared_qobject_ptr<QNetworkAccessManager> m_network; }; } diff --git a/launcher/updater/GoUpdate.cpp b/launcher/updater/GoUpdate.cpp index 6167418e..76f68b55 100644 --- a/launcher/updater/GoUpdate.cpp +++ b/launcher/updater/GoUpdate.cpp @@ -68,7 +68,7 @@ bool processFileLists const VersionFileList &newVersion, const QString &rootPath, const QString &tempPath, - NetJobPtr job, + NetJob::Ptr job, OperationList &ops ) { diff --git a/launcher/updater/GoUpdate.h b/launcher/updater/GoUpdate.h index 8058e543..46a679ef 100644 --- a/launcher/updater/GoUpdate.h +++ b/launcher/updater/GoUpdate.h @@ -117,7 +117,7 @@ bool processFileLists const VersionFileList &newVersion, const QString &rootPath, const QString &tempPath, - NetJobPtr job, + NetJob::Ptr job, OperationList &ops ); diff --git a/launcher/updater/UpdateChecker.cpp b/launcher/updater/UpdateChecker.cpp index c96a6c9f..c72bbe0b 100644 --- a/launcher/updater/UpdateChecker.cpp +++ b/launcher/updater/UpdateChecker.cpp @@ -26,8 +26,9 @@ #include "BuildConfig.h" #include "sys.h" -UpdateChecker::UpdateChecker(QString channelUrl, QString currentChannel, int currentBuild) +UpdateChecker::UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel, int currentBuild) { + m_network = nam; m_channelUrl = channelUrl; m_currentChannel = currentChannel; m_currentBuild = currentBuild; @@ -103,12 +104,11 @@ void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate) QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json")); - auto job = new NetJob("GoUpdate Repository Index"); - job->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData)); - connect(job, &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); }); - connect(job, &NetJob::failed, this, &UpdateChecker::updateCheckFailed); - indexJob.reset(job); - job->start(); + indexJob = new NetJob("GoUpdate Repository Index"); + indexJob->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData)); + connect(indexJob.get(), &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); }); + connect(indexJob.get(), &NetJob::failed, this, &UpdateChecker::updateCheckFailed); + indexJob->start(m_network); } void UpdateChecker::updateCheckFinished(bool notifyNoUpdate) @@ -191,12 +191,11 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate) } m_chanListLoading = true; - NetJob *job = new NetJob("Update System Channel List"); - job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelUrl), &chanlistData)); - connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); }); - QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed); - chanListJob.reset(job); - job->start(); + chanListJob = new NetJob("Update System Channel List"); + chanListJob->addNetAction(Net::Download::makeByteArray(QUrl(m_channelUrl), &chanlistData)); + connect(chanListJob.get(), &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); }); + connect(chanListJob.get(), &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed); + chanListJob->start(m_network); } void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate) @@ -233,10 +232,12 @@ void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate) for (QJsonValue chanVal : channelArray) { QJsonObject channelObj = chanVal.toObject(); - ChannelListEntry entry{channelObj.value("id").toVariant().toString(), - channelObj.value("name").toVariant().toString(), - channelObj.value("description").toVariant().toString(), - channelObj.value("url").toVariant().toString()}; + ChannelListEntry entry { + channelObj.value("id").toVariant().toString(), + channelObj.value("name").toVariant().toString(), + channelObj.value("description").toVariant().toString(), + channelObj.value("url").toVariant().toString() + }; if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty()) { qCritical() << "Channel list entry with empty ID, name, or URL. Skipping."; @@ -253,8 +254,9 @@ void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate) qDebug() << "Successfully loaded UpdateChecker channel list."; // If we're waiting to check for updates, do that now. - if (m_checkUpdateWaiting) + if (m_checkUpdateWaiting) { checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate); + } emit channelListLoaded(); } diff --git a/launcher/updater/UpdateChecker.h b/launcher/updater/UpdateChecker.h index 219c3c62..13ee4efd 100644 --- a/launcher/updater/UpdateChecker.h +++ b/launcher/updater/UpdateChecker.h @@ -23,7 +23,7 @@ class UpdateChecker : public QObject Q_OBJECT public: - UpdateChecker(QString channelUrl, QString currentChannel, int currentBuild); + UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel, int currentBuild); void checkForUpdate(QString updateChannel, bool notifyNoUpdate); /*! @@ -73,9 +73,11 @@ private slots: private: friend class UpdateCheckerTest; - NetJobPtr indexJob; + shared_qobject_ptr<QNetworkAccessManager> m_network; + + NetJob::Ptr indexJob; QByteArray indexData; - NetJobPtr chanListJob; + NetJob::Ptr chanListJob; QByteArray chanlistData; QString m_channelUrl; diff --git a/launcher/updater/UpdateChecker_test.cpp b/launcher/updater/UpdateChecker_test.cpp index 5702d9c6..ec55a40e 100644 --- a/launcher/updater/UpdateChecker_test.cpp +++ b/launcher/updater/UpdateChecker_test.cpp @@ -91,7 +91,8 @@ slots: QFETCH(bool, valid); QFETCH(QList<UpdateChecker::ChannelListEntry>, result); - UpdateChecker checker(channelUrl, channel, 0); + shared_qobject_ptr<QNetworkAccessManager> nam = new QNetworkAccessManager(); + UpdateChecker checker(nam, channelUrl, channel, 0); QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded())); QVERIFY(channelListLoadedSpy.isValid()); @@ -119,7 +120,8 @@ slots: QString channelUrl = findTestDataUrl("data/channels.json"); int currentBuild = 2; - UpdateChecker checker(channelUrl, channel, currentBuild); + shared_qobject_ptr<QNetworkAccessManager> nam = new QNetworkAccessManager(); + UpdateChecker checker(nam, channelUrl, channel, currentBuild); QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(GoUpdate::Status))); QVERIFY(updateAvailableSpy.isValid()); diff --git a/libraries/LocalPeer/CMakeLists.txt b/libraries/LocalPeer/CMakeLists.txt index f476da38..1e7557ec 100644 --- a/libraries/LocalPeer/CMakeLists.txt +++ b/libraries/LocalPeer/CMakeLists.txt @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.1) project(LocalPeer) -find_package(Qt5Core REQUIRED QUIET) -find_package(Qt5Network REQUIRED QUIET) +find_package(Qt5 COMPONENTS Core Network REQUIRED) set(SINGLE_SOURCES src/LocalPeer.cpp diff --git a/libraries/katabasis/CMakeLists.txt b/libraries/katabasis/CMakeLists.txt index 2f9cb66d..c6115881 100644 --- a/libraries/katabasis/CMakeLists.txt +++ b/libraries/katabasis/CMakeLists.txt @@ -27,20 +27,18 @@ set(CMAKE_C_STANDARD 11) find_package(Qt5 COMPONENTS Core Network REQUIRED) set( katabasis_PRIVATE - src/OAuth2.cpp + src/DeviceFlow.cpp src/JsonResponse.cpp src/JsonResponse.h src/PollServer.cpp src/Reply.cpp - src/ReplyServer.cpp ) set( katabasis_PUBLIC - include/katabasis/OAuth2.h + include/katabasis/DeviceFlow.h include/katabasis/Globals.h include/katabasis/PollServer.h include/katabasis/Reply.h - include/katabasis/ReplyServer.h include/katabasis/RequestParameter.h ) diff --git a/libraries/katabasis/include/katabasis/Bits.h b/libraries/katabasis/include/katabasis/Bits.h index 3fd2f530..f11f25d2 100644 --- a/libraries/katabasis/include/katabasis/Bits.h +++ b/libraries/katabasis/include/katabasis/Bits.h @@ -10,7 +10,11 @@ enum class Activity { Idle, LoggingIn, LoggingOut, - Refreshing + Refreshing, + FailedSoft, //!< soft failure. this generally means the user auth details haven't been invalidated + FailedHard, //!< hard failure. auth is invalid + FailedGone, //!< hard failure. auth is invalid, and the account no longer exists + Succeeded }; enum class Validity { diff --git a/libraries/katabasis/include/katabasis/DeviceFlow.h b/libraries/katabasis/include/katabasis/DeviceFlow.h new file mode 100644 index 00000000..b68c92e0 --- /dev/null +++ b/libraries/katabasis/include/katabasis/DeviceFlow.h @@ -0,0 +1,150 @@ +#pragma once + +#include <QNetworkAccessManager> +#include <QNetworkRequest> +#include <QNetworkReply> +#include <QPair> + +#include "Reply.h" +#include "RequestParameter.h" +#include "Bits.h" + +namespace Katabasis { + +class ReplyServer; +class PollServer; + +/// Simple OAuth2 Device Flow authenticator. +class DeviceFlow: public QObject +{ + Q_OBJECT +public: + Q_ENUMS(GrantFlow) + +public: + + struct Options { + QString userAgent = QStringLiteral("Katabasis/1.0"); + QString responseType = QStringLiteral("code"); + QString scope; + QString clientIdentifier; + QString clientSecret; + QUrl authorizationUrl; + QUrl accessTokenUrl; + }; + +public: + /// Are we authenticated? + bool linked(); + + /// Authentication token. + QString token(); + + /// Provider-specific extra tokens, available after a successful authentication + QVariantMap extraTokens(); + +public: + // TODO: put in `Options` + /// User-defined extra parameters to append to request URL + QVariantMap extraRequestParams(); + void setExtraRequestParams(const QVariantMap &value); + + // TODO: split up the class into multiple, each implementing one OAuth2 flow + /// Grant type (if non-standard) + QString grantType(); + void setGrantType(const QString &value); + +public: + /// Constructor. + /// @param parent Parent object. + explicit DeviceFlow(Options & opts, Token & token, QObject *parent = 0, QNetworkAccessManager *manager = 0); + + /// Get refresh token. + QString refreshToken(); + + /// Get token expiration time + QDateTime expires(); + +public slots: + /// Authenticate. + void login(); + + /// De-authenticate. + void logout(); + + /// Refresh token. + bool refresh(); + + /// Handle situation where reply server has opted to close its connection + void serverHasClosed(bool paramsfound = false); + +signals: + /// Emitted when client needs to open a web browser window, with the given URL. + void openBrowser(const QUrl &url); + + /// Emitted when client can close the browser window. + void closeBrowser(); + + /// Emitted when client needs to show a verification uri and user code + void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); + + /// Emitted when the internal state changes + void activityChanged(Activity activity); + +public slots: + /// Handle verification response. + void onVerificationReceived(QMap<QString, QString>); + +protected slots: + /// Handle completion of a Device Authorization Request + void onDeviceAuthReplyFinished(); + + /// Handle completion of a refresh request. + void onRefreshFinished(); + + /// Handle failure of a refresh request. + void onRefreshError(QNetworkReply::NetworkError error, QNetworkReply *reply); + +protected: + /// Set refresh token. + void setRefreshToken(const QString &v); + + /// Set token expiration time. + void setExpires(QDateTime v); + + /// Start polling authorization server + void startPollServer(const QVariantMap ¶ms, int expiresIn); + + /// Set authentication token. + void setToken(const QString &v); + + /// Set the linked state + void setLinked(bool v); + + /// Set extra tokens found in OAuth response + void setExtraTokens(QVariantMap extraTokens); + + /// Set local poll server + void setPollServer(PollServer *server); + + PollServer * pollServer() const; + + void updateActivity(Activity activity); + +protected: + Options options_; + + QVariantMap extraReqParams_; + QNetworkAccessManager *manager_ = nullptr; + ReplyList timedReplies_; + QString grantType_; + +protected: + Token &token_; + +private: + PollServer *pollServer_ = nullptr; + Activity activity_ = Activity::Idle; +}; + +} diff --git a/libraries/katabasis/include/katabasis/OAuth2.h b/libraries/katabasis/include/katabasis/OAuth2.h deleted file mode 100644 index 9dbe5c71..00000000 --- a/libraries/katabasis/include/katabasis/OAuth2.h +++ /dev/null @@ -1,233 +0,0 @@ -#pragma once - -#include <QNetworkAccessManager> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QPair> - -#include "Reply.h" -#include "RequestParameter.h" -#include "Bits.h" - -namespace Katabasis { - -class ReplyServer; -class PollServer; - - -/* - * FIXME: this is not as simple as it should be. it squishes 4 different grant flows into one big ball of mud - * This serves no practical purpose and simply makes the code less readable / maintainable. - * - * Therefore: Split this into the 4 different OAuth2 flows that people can use as authentication steps. Write tests/examples for all of them. - */ - -/// Simple OAuth2 authenticator. -class OAuth2: public QObject -{ - Q_OBJECT -public: - Q_ENUMS(GrantFlow) - -public: - - struct Options { - QString userAgent = QStringLiteral("Katabasis/1.0"); - QString redirectionUrl = QStringLiteral("http://localhost:%1"); - QString responseType = QStringLiteral("code"); - QString scope; - QString clientIdentifier; - QString clientSecret; - QUrl authorizationUrl; - QUrl accessTokenUrl; - QVector<quint16> listenerPorts = { 0 }; - }; - - /// Authorization flow types. - enum GrantFlow { - GrantFlowAuthorizationCode, ///< @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1 - GrantFlowImplicit, ///< @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.2 - GrantFlowResourceOwnerPasswordCredentials, - GrantFlowDevice ///< @see https://tools.ietf.org/html/rfc8628#section-1 - }; - - /// Authorization flow. - GrantFlow grantFlow(); - void setGrantFlow(GrantFlow value); - -public: - /// Are we authenticated? - bool linked(); - - /// Authentication token. - QString token(); - - /// Provider-specific extra tokens, available after a successful authentication - QVariantMap extraTokens(); - - /// Page content on local host after successful oauth. - /// Provide it in case you do not want to close the browser, but display something - QByteArray replyContent() const; - void setReplyContent(const QByteArray &value); - -public: - - // TODO: remove - /// Resource owner username. - /// instances with the same (username, password) share the same "linked" and "token" properties. - QString username(); - void setUsername(const QString &value); - - // TODO: remove - /// Resource owner password. - /// instances with the same (username, password) share the same "linked" and "token" properties. - QString password(); - void setPassword(const QString &value); - - // TODO: remove - /// API key. - QString apiKey(); - void setApiKey(const QString &value); - - // TODO: remove - /// Allow ignoring SSL errors? - /// E.g. SurveyMonkey fails on Mac due to SSL error. Ignoring the error circumvents the problem - bool ignoreSslErrors(); - void setIgnoreSslErrors(bool ignoreSslErrors); - - // TODO: put in `Options` - /// User-defined extra parameters to append to request URL - QVariantMap extraRequestParams(); - void setExtraRequestParams(const QVariantMap &value); - - // TODO: split up the class into multiple, each implementing one OAuth2 flow - /// Grant type (if non-standard) - QString grantType(); - void setGrantType(const QString &value); - -public: - /// Constructor. - /// @param parent Parent object. - explicit OAuth2(Options & opts, Token & token, QObject *parent = 0, QNetworkAccessManager *manager = 0); - - /// Get refresh token. - QString refreshToken(); - - /// Get token expiration time - QDateTime expires(); - -public slots: - /// Authenticate. - virtual void link(); - - /// De-authenticate. - virtual void unlink(); - - /// Refresh token. - bool refresh(); - - /// Handle situation where reply server has opted to close its connection - void serverHasClosed(bool paramsfound = false); - -signals: - /// Emitted when a token refresh has been completed or failed. - void refreshFinished(QNetworkReply::NetworkError error); - - /// Emitted when client needs to open a web browser window, with the given URL. - void openBrowser(const QUrl &url); - - /// Emitted when client can close the browser window. - void closeBrowser(); - - /// Emitted when client needs to show a verification uri and user code - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); - - /// Emitted when authentication/deauthentication succeeded. - void linkingSucceeded(); - - /// Emitted when authentication/deauthentication failed. - void linkingFailed(); - - void activityChanged(Activity activity); - -public slots: - /// Handle verification response. - virtual void onVerificationReceived(QMap<QString, QString>); - -protected slots: - /// Handle completion of a token request. - virtual void onTokenReplyFinished(); - - /// Handle failure of a token request. - virtual void onTokenReplyError(QNetworkReply::NetworkError error); - - /// Handle completion of a refresh request. - virtual void onRefreshFinished(); - - /// Handle failure of a refresh request. - virtual void onRefreshError(QNetworkReply::NetworkError error); - - /// Handle completion of a Device Authorization Request - virtual void onDeviceAuthReplyFinished(); - -protected: - /// Build HTTP request body. - QByteArray buildRequestBody(const QMap<QString, QString> ¶meters); - - /// Set refresh token. - void setRefreshToken(const QString &v); - - /// Set token expiration time. - void setExpires(QDateTime v); - - /// Start polling authorization server - void startPollServer(const QVariantMap ¶ms, int expiresIn); - - /// Set authentication token. - void setToken(const QString &v); - - /// Set the linked state - void setLinked(bool v); - - /// Set extra tokens found in OAuth response - void setExtraTokens(QVariantMap extraTokens); - - /// Set local reply server - void setReplyServer(ReplyServer *server); - - ReplyServer * replyServer() const; - - /// Set local poll server - void setPollServer(PollServer *server); - - PollServer * pollServer() const; - - void updateActivity(Activity activity); - -protected: - QString username_; - QString password_; - - Options options_; - - QVariantMap extraReqParams_; - QString apiKey_; - QNetworkAccessManager *manager_ = nullptr; - ReplyList timedReplies_; - GrantFlow grantFlow_; - QString grantType_; - -protected: - QString redirectUri_; - Token &token_; - - // this should be part of the reply server impl - QByteArray replyContent_; - -private: - ReplyServer *replyServer_ = nullptr; - PollServer *pollServer_ = nullptr; - Activity activity_ = Activity::Idle; -}; - -} diff --git a/libraries/katabasis/include/katabasis/Reply.h b/libraries/katabasis/include/katabasis/Reply.h index 3af1d49f..415cf4ec 100644 --- a/libraries/katabasis/include/katabasis/Reply.h +++ b/libraries/katabasis/include/katabasis/Reply.h @@ -9,12 +9,14 @@ namespace Katabasis { +constexpr int defaultTimeout = 30 * 1000; + /// A network request/reply pair that can time out. class Reply: public QTimer { Q_OBJECT public: - Reply(QNetworkReply *reply, int timeOut = 60 * 1000, QObject *parent = 0); + Reply(QNetworkReply *reply, int timeOut = defaultTimeout, QObject *parent = 0); signals: void error(QNetworkReply::NetworkError); @@ -25,6 +27,7 @@ public slots: public: QNetworkReply *reply; + bool timedOut = false; }; /// List of O2Replies. @@ -37,7 +40,7 @@ public: virtual ~ReplyList(); /// Create a new O2Reply from a QNetworkReply, and add it to this list. - void add(QNetworkReply *reply); + void add(QNetworkReply *reply, int timeOut = defaultTimeout); /// Add an O2Reply to the list, while taking ownership of it. void add(Reply *reply); diff --git a/libraries/katabasis/include/katabasis/ReplyServer.h b/libraries/katabasis/include/katabasis/ReplyServer.h deleted file mode 100644 index bf47df69..00000000 --- a/libraries/katabasis/include/katabasis/ReplyServer.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include <QTcpServer> -#include <QMap> -#include <QByteArray> -#include <QString> - -namespace Katabasis { - -/// HTTP server to process authentication response. -class ReplyServer: public QTcpServer { - Q_OBJECT - -public: - explicit ReplyServer(QObject *parent = 0); - - /// Page content on local host after successful oauth - in case you do not want to close the browser, but display something - Q_PROPERTY(QByteArray replyContent READ replyContent WRITE setReplyContent) - QByteArray replyContent(); - void setReplyContent(const QByteArray &value); - - /// Seconds to keep listening *after* first response for a callback with token content - Q_PROPERTY(int timeout READ timeout WRITE setTimeout) - int timeout(); - void setTimeout(int timeout); - - /// Maximum number of callback tries to accept, in case some don't have token content (favicons, etc.) - Q_PROPERTY(int callbackTries READ callbackTries WRITE setCallbackTries) - int callbackTries(); - void setCallbackTries(int maxtries); - - QString uniqueState(); - void setUniqueState(const QString &state); - -signals: - void verificationReceived(QMap<QString, QString>); - void serverClosed(bool); // whether it has found parameters - -public slots: - void onIncomingConnection(); - void onBytesReady(); - QMap<QString, QString> parseQueryParams(QByteArray *data); - void closeServer(QTcpSocket *socket = 0, bool hasparameters = false); - -protected: - QByteArray replyContent_; - int timeout_; - int maxtries_; - int tries_; - QString uniqueState_; -}; - -} diff --git a/libraries/katabasis/src/DeviceFlow.cpp b/libraries/katabasis/src/DeviceFlow.cpp new file mode 100644 index 00000000..ba1d121d --- /dev/null +++ b/libraries/katabasis/src/DeviceFlow.cpp @@ -0,0 +1,451 @@ +#include <QList> +#include <QPair> +#include <QDebug> +#include <QTcpServer> +#include <QMap> +#include <QNetworkRequest> +#include <QNetworkReply> +#include <QNetworkAccessManager> +#include <QDateTime> +#include <QCryptographicHash> +#include <QTimer> +#include <QVariantMap> +#include <QUuid> +#include <QDataStream> + +#include <QUrlQuery> + +#include "katabasis/DeviceFlow.h" +#include "katabasis/PollServer.h" +#include "katabasis/Globals.h" + +#include "JsonResponse.h" + +namespace { +// ref: https://tools.ietf.org/html/rfc8628#section-3.2 +// Exception: Google sign-in uses "verification_url" instead of "*_uri" - we'll accept both. +bool hasMandatoryDeviceAuthParams(const QVariantMap& params) +{ + if (!params.contains(Katabasis::OAUTH2_DEVICE_CODE)) + return false; + + if (!params.contains(Katabasis::OAUTH2_USER_CODE)) + return false; + + if (!(params.contains(Katabasis::OAUTH2_VERIFICATION_URI) || params.contains(Katabasis::OAUTH2_VERIFICATION_URL))) + return false; + + if (!params.contains(Katabasis::OAUTH2_EXPIRES_IN)) + return false; + + return true; +} + +QByteArray createQueryParameters(const QList<Katabasis::RequestParameter> ¶meters) { + QByteArray ret; + bool first = true; + for( auto & h: parameters) { + if (first) { + first = false; + } else { + ret.append("&"); + } + ret.append(QUrl::toPercentEncoding(h.name) + "=" + QUrl::toPercentEncoding(h.value)); + } + return ret; +} +} + +namespace Katabasis { + +DeviceFlow::DeviceFlow(Options & opts, Token & token, QObject *parent, QNetworkAccessManager *manager) : QObject(parent), token_(token) { + manager_ = manager ? manager : new QNetworkAccessManager(this); + qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); + options_ = opts; +} + +bool DeviceFlow::linked() { + return token_.validity != Validity::None; +} +void DeviceFlow::setLinked(bool v) { + qDebug() << "DeviceFlow::setLinked:" << (v? "true": "false"); + token_.validity = v ? Validity::Certain : Validity::None; +} + +void DeviceFlow::updateActivity(Activity activity) +{ + if(activity_ == activity) { + return; + } + + activity_ = activity; + switch(activity) { + case Katabasis::Activity::Idle: + case Katabasis::Activity::LoggingIn: + case Katabasis::Activity::LoggingOut: + case Katabasis::Activity::Refreshing: + // non-terminal states... + break; + case Katabasis::Activity::FailedSoft: + // terminal state, tokens did not change + break; + case Katabasis::Activity::FailedHard: + case Katabasis::Activity::FailedGone: + // terminal state, tokens are invalid + token_ = Token(); + break; + case Katabasis::Activity::Succeeded: + setLinked(true); + break; + } + emit activityChanged(activity_); +} + +QString DeviceFlow::token() { + return token_.token; +} +void DeviceFlow::setToken(const QString &v) { + token_.token = v; +} + +QVariantMap DeviceFlow::extraTokens() { + return token_.extra; +} + +void DeviceFlow::setExtraTokens(QVariantMap extraTokens) { + token_.extra = extraTokens; +} + +void DeviceFlow::setPollServer(PollServer *server) +{ + if (pollServer_) + pollServer_->deleteLater(); + + pollServer_ = server; +} + +PollServer *DeviceFlow::pollServer() const +{ + return pollServer_; +} + +QVariantMap DeviceFlow::extraRequestParams() +{ + return extraReqParams_; +} + +void DeviceFlow::setExtraRequestParams(const QVariantMap &value) +{ + extraReqParams_ = value; +} + +QString DeviceFlow::grantType() +{ + if (!grantType_.isEmpty()) + return grantType_; + + return OAUTH2_GRANT_TYPE_DEVICE; +} + +void DeviceFlow::setGrantType(const QString &value) +{ + grantType_ = value; +} + +// First get the URL and token to display to the user +void DeviceFlow::login() { + qDebug() << "DeviceFlow::link"; + + updateActivity(Activity::LoggingIn); + setLinked(false); + setToken(""); + setExtraTokens(QVariantMap()); + setRefreshToken(QString()); + setExpires(QDateTime()); + + QList<RequestParameter> parameters; + parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); + parameters.append(RequestParameter(OAUTH2_SCOPE, options_.scope.toUtf8())); + QByteArray payload = createQueryParameters(parameters); + + QUrl url(options_.authorizationUrl); + QNetworkRequest deviceRequest(url); + deviceRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + QNetworkReply *tokenReply = manager_->post(deviceRequest, payload); + + connect(tokenReply, &QNetworkReply::finished, this, &DeviceFlow::onDeviceAuthReplyFinished, Qt::QueuedConnection); +} + +// Then, once we get them, present them to the user +void DeviceFlow::onDeviceAuthReplyFinished() +{ + qDebug() << "DeviceFlow::onDeviceAuthReplyFinished"; + QNetworkReply *tokenReply = qobject_cast<QNetworkReply *>(sender()); + if (!tokenReply) + { + qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: reply is null"; + return; + } + if (tokenReply->error() == QNetworkReply::NoError) { + QByteArray replyData = tokenReply->readAll(); + + // Dump replyData + // SENSITIVE DATA in RelWithDebInfo or Debug builds + //qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: replyData\n"; + //qDebug() << QString( replyData ); + + QVariantMap params = parseJsonResponse(replyData); + + // Dump tokens + qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: Tokens returned:\n"; + foreach (QString key, params.keys()) { + // SENSITIVE DATA in RelWithDebInfo or Debug builds, so it is truncated first + qDebug() << key << ": "<< params.value( key ).toString(); + } + + // Check for mandatory parameters + if (hasMandatoryDeviceAuthParams(params)) { + qDebug() << "DeviceFlow::onDeviceAuthReplyFinished: Device auth request response"; + + const QString userCode = params.take(OAUTH2_USER_CODE).toString(); + QUrl uri = params.take(OAUTH2_VERIFICATION_URI).toUrl(); + if (uri.isEmpty()) + uri = params.take(OAUTH2_VERIFICATION_URL).toUrl(); + + if (params.contains(OAUTH2_VERIFICATION_URI_COMPLETE)) + emit openBrowser(params.take(OAUTH2_VERIFICATION_URI_COMPLETE).toUrl()); + + bool ok = false; + int expiresIn = params[OAUTH2_EXPIRES_IN].toInt(&ok); + if (!ok) { + qWarning() << "DeviceFlow::startPollServer: No expired_in parameter"; + updateActivity(Activity::FailedHard); + return; + } + + emit showVerificationUriAndCode(uri, userCode, expiresIn); + + startPollServer(params, expiresIn); + } else { + qWarning() << "DeviceFlow::onDeviceAuthReplyFinished: Mandatory parameters missing from response"; + updateActivity(Activity::FailedHard); + } + } + tokenReply->deleteLater(); +} + +// Spin up polling for the user completing the login flow out of band +void DeviceFlow::startPollServer(const QVariantMap ¶ms, int expiresIn) +{ + qDebug() << "DeviceFlow::startPollServer: device_ and user_code expires in" << expiresIn << "seconds"; + + QUrl url(options_.accessTokenUrl); + QNetworkRequest authRequest(url); + authRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + const QString deviceCode = params[OAUTH2_DEVICE_CODE].toString(); + const QString grantType = grantType_.isEmpty() ? OAUTH2_GRANT_TYPE_DEVICE : grantType_; + + QList<RequestParameter> parameters; + parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); + if ( !options_.clientSecret.isEmpty() ) { + parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8())); + } + parameters.append(RequestParameter(OAUTH2_CODE, deviceCode.toUtf8())); + parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, grantType.toUtf8())); + QByteArray payload = createQueryParameters(parameters); + + PollServer * pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this); + if (params.contains(OAUTH2_INTERVAL)) { + bool ok = false; + int interval = params[OAUTH2_INTERVAL].toInt(&ok); + if (ok) { + pollServer->setInterval(interval); + } + } + connect(pollServer, &PollServer::verificationReceived, this, &DeviceFlow::onVerificationReceived); + connect(pollServer, &PollServer::serverClosed, this, &DeviceFlow::serverHasClosed); + setPollServer(pollServer); + pollServer->startPolling(); +} + +// Once the user completes the flow, update the internal state and report it to observers +void DeviceFlow::onVerificationReceived(const QMap<QString, QString> response) { + qDebug() << "DeviceFlow::onVerificationReceived: Emitting closeBrowser()"; + emit closeBrowser(); + + if (response.contains("error")) { + qWarning() << "DeviceFlow::onVerificationReceived: Verification failed:" << response; + updateActivity(Activity::FailedHard); + return; + } + + // Check for mandatory tokens + if (response.contains(OAUTH2_ACCESS_TOKEN)) { + qDebug() << "DeviceFlow::onVerificationReceived: Access token returned for implicit or device flow"; + setToken(response.value(OAUTH2_ACCESS_TOKEN)); + if (response.contains(OAUTH2_EXPIRES_IN)) { + bool ok = false; + int expiresIn = response.value(OAUTH2_EXPIRES_IN).toInt(&ok); + if (ok) { + qDebug() << "DeviceFlow::onVerificationReceived: Token expires in" << expiresIn << "seconds"; + setExpires(QDateTime::currentDateTimeUtc().addSecs(expiresIn)); + } + } + if (response.contains(OAUTH2_REFRESH_TOKEN)) { + setRefreshToken(response.value(OAUTH2_REFRESH_TOKEN)); + } + updateActivity(Activity::Succeeded); + } else { + qWarning() << "DeviceFlow::onVerificationReceived: Access token missing from response for implicit or device flow"; + updateActivity(Activity::FailedHard); + } +} + +// Or if the flow fails or the polling times out, update the internal state with error and report it to observers +void DeviceFlow::serverHasClosed(bool paramsfound) +{ + if ( !paramsfound ) { + // server has probably timed out after receiving first response + updateActivity(Activity::FailedHard); + } + // poll server is not re-used for later auth requests + setPollServer(NULL); +} + +void DeviceFlow::logout() { + qDebug() << "DeviceFlow::unlink"; + updateActivity(Activity::LoggingOut); + // FIXME: implement logout flows... if they exist + token_ = Token(); + updateActivity(Activity::FailedHard); +} + +QDateTime DeviceFlow::expires() { + return token_.notAfter; +} +void DeviceFlow::setExpires(QDateTime v) { + token_.notAfter = v; +} + +QString DeviceFlow::refreshToken() { + return token_.refresh_token; +} + +void DeviceFlow::setRefreshToken(const QString &v) { +#ifndef NDEBUG + qDebug() << "DeviceFlow::setRefreshToken" << v << "..."; +#endif + token_.refresh_token = v; +} + +namespace { +QByteArray buildRequestBody(const QMap<QString, QString> ¶meters) { + QByteArray body; + bool first = true; + foreach (QString key, parameters.keys()) { + if (first) { + first = false; + } else { + body.append("&"); + } + QString value = parameters.value(key); + body.append(QUrl::toPercentEncoding(key) + QString("=").toUtf8() + QUrl::toPercentEncoding(value)); + } + return body; +} +} + +bool DeviceFlow::refresh() { + qDebug() << "DeviceFlow::refresh: Token: ..." << refreshToken().right(7); + + updateActivity(Activity::Refreshing); + + if (refreshToken().isEmpty()) { + qWarning() << "DeviceFlow::refresh: No refresh token"; + onRefreshError(QNetworkReply::AuthenticationRequiredError, nullptr); + return false; + } + if (options_.accessTokenUrl.isEmpty()) { + qWarning() << "DeviceFlow::refresh: Refresh token URL not set"; + onRefreshError(QNetworkReply::AuthenticationRequiredError, nullptr); + return false; + } + + QNetworkRequest refreshRequest(options_.accessTokenUrl); + refreshRequest.setHeader(QNetworkRequest::ContentTypeHeader, MIME_TYPE_XFORM); + QMap<QString, QString> parameters; + parameters.insert(OAUTH2_CLIENT_ID, options_.clientIdentifier); + if ( !options_.clientSecret.isEmpty() ) { + parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret); + } + parameters.insert(OAUTH2_REFRESH_TOKEN, refreshToken()); + parameters.insert(OAUTH2_GRANT_TYPE, OAUTH2_REFRESH_TOKEN); + + QByteArray data = buildRequestBody(parameters); + QNetworkReply *refreshReply = manager_->post(refreshRequest, data); + timedReplies_.add(refreshReply); + connect(refreshReply, &QNetworkReply::finished, this, &DeviceFlow::onRefreshFinished, Qt::QueuedConnection); + return true; +} + +void DeviceFlow::onRefreshFinished() { + QNetworkReply *refreshReply = qobject_cast<QNetworkReply *>(sender()); + + auto networkError = refreshReply->error(); + if (networkError == QNetworkReply::NoError) { + QByteArray reply = refreshReply->readAll(); + QVariantMap tokens = parseJsonResponse(reply); + setToken(tokens.value(OAUTH2_ACCESS_TOKEN).toString()); + setExpires(QDateTime::currentDateTimeUtc().addSecs(tokens.value(OAUTH2_EXPIRES_IN).toInt())); + QString refreshToken = tokens.value(OAUTH2_REFRESH_TOKEN).toString(); + if(!refreshToken.isEmpty()) { + setRefreshToken(refreshToken); + } + else { + qDebug() << "No new refresh token. Keep the old one."; + } + timedReplies_.remove(refreshReply); + refreshReply->deleteLater(); + updateActivity(Activity::Succeeded); + qDebug() << "New token expires in" << expires() << "seconds"; + } else { + // FIXME: differentiate the error more here + onRefreshError(networkError, refreshReply); + } +} + +void DeviceFlow::onRefreshError(QNetworkReply::NetworkError error, QNetworkReply *refreshReply) { + QString errorString = "No Reply"; + if(refreshReply) { + timedReplies_.remove(refreshReply); + errorString = refreshReply->errorString(); + } + + switch (error) + { + // used for invalid credentials and similar errors. Fall through. + case QNetworkReply::AuthenticationRequiredError: + case QNetworkReply::ContentAccessDenied: + case QNetworkReply::ContentOperationNotPermittedError: + case QNetworkReply::ProtocolInvalidOperationError: + updateActivity(Activity::FailedHard); + break; + case QNetworkReply::ContentGoneError: { + updateActivity(Activity::FailedGone); + break; + } + case QNetworkReply::TimeoutError: + case QNetworkReply::OperationCanceledError: + case QNetworkReply::SslHandshakeFailedError: + default: + updateActivity(Activity::FailedSoft); + return; + } + if(refreshReply) { + refreshReply->deleteLater(); + } + qDebug() << "DeviceFlow::onRefreshFinished: Error" << (int)error << " - " << errorString; +} + +} diff --git a/libraries/katabasis/src/OAuth2.cpp b/libraries/katabasis/src/OAuth2.cpp deleted file mode 100644 index 260aa9c1..00000000 --- a/libraries/katabasis/src/OAuth2.cpp +++ /dev/null @@ -1,672 +0,0 @@ -#include <QList> -#include <QPair> -#include <QDebug> -#include <QTcpServer> -#include <QMap> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QNetworkAccessManager> -#include <QDateTime> -#include <QCryptographicHash> -#include <QTimer> -#include <QVariantMap> -#include <QUuid> -#include <QDataStream> - -#include <QUrlQuery> - -#include "katabasis/OAuth2.h" -#include "katabasis/PollServer.h" -#include "katabasis/ReplyServer.h" -#include "katabasis/Globals.h" - -#include "JsonResponse.h" - -namespace { -// ref: https://tools.ietf.org/html/rfc8628#section-3.2 -// Exception: Google sign-in uses "verification_url" instead of "*_uri" - we'll accept both. -bool hasMandatoryDeviceAuthParams(const QVariantMap& params) -{ - if (!params.contains(Katabasis::OAUTH2_DEVICE_CODE)) - return false; - - if (!params.contains(Katabasis::OAUTH2_USER_CODE)) - return false; - - if (!(params.contains(Katabasis::OAUTH2_VERIFICATION_URI) || params.contains(Katabasis::OAUTH2_VERIFICATION_URL))) - return false; - - if (!params.contains(Katabasis::OAUTH2_EXPIRES_IN)) - return false; - - return true; -} - -QByteArray createQueryParameters(const QList<Katabasis::RequestParameter> ¶meters) { - QByteArray ret; - bool first = true; - for( auto & h: parameters) { - if (first) { - first = false; - } else { - ret.append("&"); - } - ret.append(QUrl::toPercentEncoding(h.name) + "=" + QUrl::toPercentEncoding(h.value)); - } - return ret; -} -} - -namespace Katabasis { - -OAuth2::OAuth2(Options & opts, Token & token, QObject *parent, QNetworkAccessManager *manager) : QObject(parent), token_(token) { - manager_ = manager ? manager : new QNetworkAccessManager(this); - grantFlow_ = GrantFlowAuthorizationCode; - qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); - options_ = opts; -} - -bool OAuth2::linked() { - return token_.validity != Validity::None; -} -void OAuth2::setLinked(bool v) { - qDebug() << "OAuth2::setLinked:" << (v? "true": "false"); - token_.validity = v ? Validity::Certain : Validity::None; -} - -QString OAuth2::token() { - return token_.token; -} -void OAuth2::setToken(const QString &v) { - token_.token = v; -} - -QByteArray OAuth2::replyContent() const { - return replyContent_; -} - -void OAuth2::setReplyContent(const QByteArray &value) { - replyContent_ = value; - if (replyServer_) { - replyServer_->setReplyContent(replyContent_); - } -} - -QVariantMap OAuth2::extraTokens() { - return token_.extra; -} - -void OAuth2::setExtraTokens(QVariantMap extraTokens) { - token_.extra = extraTokens; -} - -void OAuth2::setReplyServer(ReplyServer * server) -{ - delete replyServer_; - - replyServer_ = server; - replyServer_->setReplyContent(replyContent_); -} - -ReplyServer * OAuth2::replyServer() const -{ - return replyServer_; -} - -void OAuth2::setPollServer(PollServer *server) -{ - if (pollServer_) - pollServer_->deleteLater(); - - pollServer_ = server; -} - -PollServer *OAuth2::pollServer() const -{ - return pollServer_; -} - -OAuth2::GrantFlow OAuth2::grantFlow() { - return grantFlow_; -} - -void OAuth2::setGrantFlow(OAuth2::GrantFlow value) { - grantFlow_ = value; -} - -QString OAuth2::username() { - return username_; -} - -void OAuth2::setUsername(const QString &value) { - username_ = value; -} - -QString OAuth2::password() { - return password_; -} - -void OAuth2::setPassword(const QString &value) { - password_ = value; -} - -QVariantMap OAuth2::extraRequestParams() -{ - return extraReqParams_; -} - -void OAuth2::setExtraRequestParams(const QVariantMap &value) -{ - extraReqParams_ = value; -} - -QString OAuth2::grantType() -{ - if (!grantType_.isEmpty()) - return grantType_; - - switch (grantFlow_) { - case GrantFlowAuthorizationCode: - return OAUTH2_GRANT_TYPE_CODE; - case GrantFlowImplicit: - return OAUTH2_GRANT_TYPE_TOKEN; - case GrantFlowResourceOwnerPasswordCredentials: - return OAUTH2_GRANT_TYPE_PASSWORD; - case GrantFlowDevice: - return OAUTH2_GRANT_TYPE_DEVICE; - } - - return QString(); -} - -void OAuth2::setGrantType(const QString &value) -{ - grantType_ = value; -} - -void OAuth2::updateActivity(Activity activity) -{ - if(activity_ != activity) { - activity_ = activity; - emit activityChanged(activity_); - } -} - -void OAuth2::link() { - qDebug() << "OAuth2::link"; - - // Create the reply server if it doesn't exist - if(replyServer() == NULL) { - ReplyServer * replyServer = new ReplyServer(this); - connect(replyServer, &ReplyServer::verificationReceived, this, &OAuth2::onVerificationReceived); - connect(replyServer, &ReplyServer::serverClosed, this, &OAuth2::serverHasClosed); - setReplyServer(replyServer); - } - - if (linked()) { - qDebug() << "OAuth2::link: Linked already"; - emit linkingSucceeded(); - return; - } - - setLinked(false); - setToken(""); - setExtraTokens(QVariantMap()); - setRefreshToken(QString()); - setExpires(QDateTime()); - - if (grantFlow_ == GrantFlowAuthorizationCode || grantFlow_ == GrantFlowImplicit) { - - QString uniqueState = QUuid::createUuid().toString().remove(QRegExp("([^a-zA-Z0-9]|[-])")); - - // FIXME: this should be part of a 'redirection handler' that would get injected into O2 - { - quint16 foundPort = 0; - // Start listening to authentication replies - if (!replyServer()->isListening()) { - auto ports = options_.listenerPorts; - for(auto & port: ports) { - if (replyServer()->listen(QHostAddress::Any, port)) { - foundPort = replyServer()->serverPort(); - qDebug() << "OAuth2::link: Reply server listening on port " << foundPort; - break; - } - } - if(foundPort == 0) { - qWarning() << "OAuth2::link: Reply server failed to start listening on any port out of " << ports; - emit linkingFailed(); - return; - } - } - - // Save redirect URI, as we have to reuse it when requesting the access token - redirectUri_ = options_.redirectionUrl.arg(foundPort); - replyServer()->setUniqueState(uniqueState); - } - - // Assemble intial authentication URL - QUrl url(options_.authorizationUrl); - QUrlQuery query(url); - QList<QPair<QString, QString> > parameters; - query.addQueryItem(OAUTH2_RESPONSE_TYPE, (grantFlow_ == GrantFlowAuthorizationCode)? OAUTH2_GRANT_TYPE_CODE: OAUTH2_GRANT_TYPE_TOKEN); - query.addQueryItem(OAUTH2_CLIENT_ID, options_.clientIdentifier); - query.addQueryItem(OAUTH2_REDIRECT_URI, redirectUri_); - query.addQueryItem(OAUTH2_SCOPE, options_.scope.replace( " ", "+" )); - query.addQueryItem(OAUTH2_STATE, uniqueState); - if (!apiKey_.isEmpty()) { - query.addQueryItem(OAUTH2_API_KEY, apiKey_); - } - for(auto iter = extraReqParams_.begin(); iter != extraReqParams_.end(); iter++) { - query.addQueryItem(iter.key(), iter.value().toString()); - } - url.setQuery(query); - - // Show authentication URL with a web browser - qDebug() << "OAuth2::link: Emit openBrowser" << url.toString(); - emit openBrowser(url); - updateActivity(Activity::LoggingIn); - } else if (grantFlow_ == GrantFlowResourceOwnerPasswordCredentials) { - QList<RequestParameter> parameters; - parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); - if ( !options_.clientSecret.isEmpty() ) { - parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8())); - } - parameters.append(RequestParameter(OAUTH2_USERNAME, username_.toUtf8())); - parameters.append(RequestParameter(OAUTH2_PASSWORD, password_.toUtf8())); - parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, OAUTH2_GRANT_TYPE_PASSWORD)); - parameters.append(RequestParameter(OAUTH2_SCOPE, options_.scope.toUtf8())); - if ( !apiKey_.isEmpty() ) - parameters.append(RequestParameter(OAUTH2_API_KEY, apiKey_.toUtf8())); - foreach (QString key, extraRequestParams().keys()) { - parameters.append(RequestParameter(key.toUtf8(), extraRequestParams().value(key).toByteArray())); - } - QByteArray payload = createQueryParameters(parameters); - - qDebug() << "OAuth2::link: Sending token request for resource owner flow"; - QUrl url(options_.accessTokenUrl); - QNetworkRequest tokenRequest(url); - tokenRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - QNetworkReply *tokenReply = manager_->post(tokenRequest, payload); - - connect(tokenReply, SIGNAL(finished()), this, SLOT(onTokenReplyFinished()), Qt::QueuedConnection); - connect(tokenReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onTokenReplyError(QNetworkReply::NetworkError)), Qt::QueuedConnection); - updateActivity(Activity::LoggingIn); - } - else if (grantFlow_ == GrantFlowDevice) { - QList<RequestParameter> parameters; - parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); - parameters.append(RequestParameter(OAUTH2_SCOPE, options_.scope.toUtf8())); - QByteArray payload = createQueryParameters(parameters); - - QUrl url(options_.authorizationUrl); - QNetworkRequest deviceRequest(url); - deviceRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - QNetworkReply *tokenReply = manager_->post(deviceRequest, payload); - - connect(tokenReply, SIGNAL(finished()), this, SLOT(onDeviceAuthReplyFinished()), Qt::QueuedConnection); - connect(tokenReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onTokenReplyError(QNetworkReply::NetworkError)), Qt::QueuedConnection); - updateActivity(Activity::LoggingIn); - } -} - -void OAuth2::unlink() { - qDebug() << "OAuth2::unlink"; - updateActivity(Activity::LoggingOut); - // FIXME: implement logout flows... if they exist - token_ = Token(); - updateActivity(Activity::Idle); -} - -void OAuth2::onVerificationReceived(const QMap<QString, QString> response) { - qDebug() << "OAuth2::onVerificationReceived: Emitting closeBrowser()"; - emit closeBrowser(); - - if (response.contains("error")) { - qWarning() << "OAuth2::onVerificationReceived: Verification failed:" << response; - emit linkingFailed(); - updateActivity(Activity::Idle); - return; - } - - if (grantFlow_ == GrantFlowAuthorizationCode) { - // NOTE: access code is temporary and should never be saved anywhere! - auto access_code = response.value(QString(OAUTH2_GRANT_TYPE_CODE)); - - // Exchange access code for access/refresh tokens - QString query; - if(!apiKey_.isEmpty()) - query = QString("?" + QString(OAUTH2_API_KEY) + "=" + apiKey_); - QNetworkRequest tokenRequest(QUrl(options_.accessTokenUrl.toString() + query)); - tokenRequest.setHeader(QNetworkRequest::ContentTypeHeader, MIME_TYPE_XFORM); - tokenRequest.setRawHeader("Accept", MIME_TYPE_JSON); - QMap<QString, QString> parameters; - parameters.insert(OAUTH2_GRANT_TYPE_CODE, access_code); - parameters.insert(OAUTH2_CLIENT_ID, options_.clientIdentifier); - if ( !options_.clientSecret.isEmpty() ) { - parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret); - } - parameters.insert(OAUTH2_REDIRECT_URI, redirectUri_); - parameters.insert(OAUTH2_GRANT_TYPE, AUTHORIZATION_CODE); - QByteArray data = buildRequestBody(parameters); - - qDebug() << QString("OAuth2::onVerificationReceived: Exchange access code data:\n%1").arg(QString(data)); - - QNetworkReply *tokenReply = manager_->post(tokenRequest, data); - timedReplies_.add(tokenReply); - connect(tokenReply, SIGNAL(finished()), this, SLOT(onTokenReplyFinished()), Qt::QueuedConnection); - connect(tokenReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onTokenReplyError(QNetworkReply::NetworkError)), Qt::QueuedConnection); - } else if (grantFlow_ == GrantFlowImplicit || grantFlow_ == GrantFlowDevice) { - // Check for mandatory tokens - if (response.contains(OAUTH2_ACCESS_TOKEN)) { - qDebug() << "OAuth2::onVerificationReceived: Access token returned for implicit or device flow"; - setToken(response.value(OAUTH2_ACCESS_TOKEN)); - if (response.contains(OAUTH2_EXPIRES_IN)) { - bool ok = false; - int expiresIn = response.value(OAUTH2_EXPIRES_IN).toInt(&ok); - if (ok) { - qDebug() << "OAuth2::onVerificationReceived: Token expires in" << expiresIn << "seconds"; - setExpires(QDateTime::currentDateTimeUtc().addSecs(expiresIn)); - } - } - if (response.contains(OAUTH2_REFRESH_TOKEN)) { - setRefreshToken(response.value(OAUTH2_REFRESH_TOKEN)); - } - setLinked(true); - emit linkingSucceeded(); - } else { - qWarning() << "OAuth2::onVerificationReceived: Access token missing from response for implicit or device flow"; - emit linkingFailed(); - } - updateActivity(Activity::Idle); - } else { - setToken(response.value(OAUTH2_ACCESS_TOKEN)); - setRefreshToken(response.value(OAUTH2_REFRESH_TOKEN)); - updateActivity(Activity::Idle); - } -} - -void OAuth2::onTokenReplyFinished() { - qDebug() << "OAuth2::onTokenReplyFinished"; - QNetworkReply *tokenReply = qobject_cast<QNetworkReply *>(sender()); - if (!tokenReply) - { - qDebug() << "OAuth2::onTokenReplyFinished: reply is null"; - return; - } - if (tokenReply->error() == QNetworkReply::NoError) { - QByteArray replyData = tokenReply->readAll(); - - // Dump replyData - // SENSITIVE DATA in RelWithDebInfo or Debug builds - //qDebug() << "OAuth2::onTokenReplyFinished: replyData\n"; - //qDebug() << QString( replyData ); - - QVariantMap tokens = parseJsonResponse(replyData); - - // Dump tokens - qDebug() << "OAuth2::onTokenReplyFinished: Tokens returned:\n"; - foreach (QString key, tokens.keys()) { - // SENSITIVE DATA in RelWithDebInfo or Debug builds, so it is truncated first - qDebug() << key << ": "<< tokens.value( key ).toString(); - } - - // Check for mandatory tokens - if (tokens.contains(OAUTH2_ACCESS_TOKEN)) { - qDebug() << "OAuth2::onTokenReplyFinished: Access token returned"; - setToken(tokens.take(OAUTH2_ACCESS_TOKEN).toString()); - bool ok = false; - int expiresIn = tokens.take(OAUTH2_EXPIRES_IN).toInt(&ok); - if (ok) { - qDebug() << "OAuth2::onTokenReplyFinished: Token expires in" << expiresIn << "seconds"; - setExpires(QDateTime::currentDateTimeUtc().addSecs(expiresIn)); - } - setRefreshToken(tokens.take(OAUTH2_REFRESH_TOKEN).toString()); - setExtraTokens(tokens); - timedReplies_.remove(tokenReply); - setLinked(true); - emit linkingSucceeded(); - } else { - qWarning() << "OAuth2::onTokenReplyFinished: Access token missing from response"; - emit linkingFailed(); - } - } - tokenReply->deleteLater(); - updateActivity(Activity::Idle); -} - -void OAuth2::onTokenReplyError(QNetworkReply::NetworkError error) { - QNetworkReply *tokenReply = qobject_cast<QNetworkReply *>(sender()); - if (!tokenReply) - { - qDebug() << "OAuth2::onTokenReplyError: reply is null"; - } else { - qWarning() << "OAuth2::onTokenReplyError: " << error << ": " << tokenReply->errorString(); - qDebug() << "OAuth2::onTokenReplyError: " << tokenReply->readAll(); - timedReplies_.remove(tokenReply); - } - - setToken(QString()); - setRefreshToken(QString()); - emit linkingFailed(); -} - -QByteArray OAuth2::buildRequestBody(const QMap<QString, QString> ¶meters) { - QByteArray body; - bool first = true; - foreach (QString key, parameters.keys()) { - if (first) { - first = false; - } else { - body.append("&"); - } - QString value = parameters.value(key); - body.append(QUrl::toPercentEncoding(key) + QString("=").toUtf8() + QUrl::toPercentEncoding(value)); - } - return body; -} - -QDateTime OAuth2::expires() { - return token_.notAfter; -} -void OAuth2::setExpires(QDateTime v) { - token_.notAfter = v; -} - -void OAuth2::startPollServer(const QVariantMap ¶ms, int expiresIn) -{ - qDebug() << "OAuth2::startPollServer: device_ and user_code expires in" << expiresIn << "seconds"; - - QUrl url(options_.accessTokenUrl); - QNetworkRequest authRequest(url); - authRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - - const QString deviceCode = params[OAUTH2_DEVICE_CODE].toString(); - const QString grantType = grantType_.isEmpty() ? OAUTH2_GRANT_TYPE_DEVICE : grantType_; - - QList<RequestParameter> parameters; - parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); - if ( !options_.clientSecret.isEmpty() ) { - parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8())); - } - parameters.append(RequestParameter(OAUTH2_CODE, deviceCode.toUtf8())); - parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, grantType.toUtf8())); - QByteArray payload = createQueryParameters(parameters); - - PollServer * pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this); - if (params.contains(OAUTH2_INTERVAL)) { - bool ok = false; - int interval = params[OAUTH2_INTERVAL].toInt(&ok); - if (ok) - pollServer->setInterval(interval); - } - connect(pollServer, SIGNAL(verificationReceived(QMap<QString,QString>)), this, SLOT(onVerificationReceived(QMap<QString,QString>))); - connect(pollServer, SIGNAL(serverClosed(bool)), this, SLOT(serverHasClosed(bool))); - setPollServer(pollServer); - pollServer->startPolling(); -} - -QString OAuth2::refreshToken() { - return token_.refresh_token; -} -void OAuth2::setRefreshToken(const QString &v) { -#ifndef NDEBUG - qDebug() << "OAuth2::setRefreshToken" << v << "..."; -#endif - token_.refresh_token = v; -} - -bool OAuth2::refresh() { - qDebug() << "OAuth2::refresh: Token: ..." << refreshToken().right(7); - - if (refreshToken().isEmpty()) { - qWarning() << "OAuth2::refresh: No refresh token"; - onRefreshError(QNetworkReply::AuthenticationRequiredError); - return false; - } - if (options_.accessTokenUrl.isEmpty()) { - qWarning() << "OAuth2::refresh: Refresh token URL not set"; - onRefreshError(QNetworkReply::AuthenticationRequiredError); - return false; - } - - updateActivity(Activity::Refreshing); - - QNetworkRequest refreshRequest(options_.accessTokenUrl); - refreshRequest.setHeader(QNetworkRequest::ContentTypeHeader, MIME_TYPE_XFORM); - QMap<QString, QString> parameters; - parameters.insert(OAUTH2_CLIENT_ID, options_.clientIdentifier); - if ( !options_.clientSecret.isEmpty() ) { - parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret); - } - parameters.insert(OAUTH2_REFRESH_TOKEN, refreshToken()); - parameters.insert(OAUTH2_GRANT_TYPE, OAUTH2_REFRESH_TOKEN); - - QByteArray data = buildRequestBody(parameters); - QNetworkReply *refreshReply = manager_->post(refreshRequest, data); - timedReplies_.add(refreshReply); - connect(refreshReply, SIGNAL(finished()), this, SLOT(onRefreshFinished()), Qt::QueuedConnection); - connect(refreshReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRefreshError(QNetworkReply::NetworkError)), Qt::QueuedConnection); - return true; -} - -void OAuth2::onRefreshFinished() { - QNetworkReply *refreshReply = qobject_cast<QNetworkReply *>(sender()); - - if (refreshReply->error() == QNetworkReply::NoError) { - QByteArray reply = refreshReply->readAll(); - QVariantMap tokens = parseJsonResponse(reply); - setToken(tokens.value(OAUTH2_ACCESS_TOKEN).toString()); - setExpires(QDateTime::currentDateTimeUtc().addSecs(tokens.value(OAUTH2_EXPIRES_IN).toInt())); - QString refreshToken = tokens.value(OAUTH2_REFRESH_TOKEN).toString(); - if(!refreshToken.isEmpty()) { - setRefreshToken(refreshToken); - } - else { - qDebug() << "No new refresh token. Keep the old one."; - } - timedReplies_.remove(refreshReply); - setLinked(true); - emit linkingSucceeded(); - emit refreshFinished(QNetworkReply::NoError); - qDebug() << "New token expires in" << expires() << "seconds"; - } else { - emit linkingFailed(); - qDebug() << "OAuth2::onRefreshFinished: Error" << (int)refreshReply->error() << refreshReply->errorString(); - } - refreshReply->deleteLater(); - updateActivity(Activity::Idle); -} - -void OAuth2::onRefreshError(QNetworkReply::NetworkError error) { - QNetworkReply *refreshReply = qobject_cast<QNetworkReply *>(sender()); - qWarning() << "OAuth2::onRefreshError: " << error; - unlink(); - timedReplies_.remove(refreshReply); - emit refreshFinished(error); -} - -void OAuth2::onDeviceAuthReplyFinished() -{ - qDebug() << "OAuth2::onDeviceAuthReplyFinished"; - QNetworkReply *tokenReply = qobject_cast<QNetworkReply *>(sender()); - if (!tokenReply) - { - qDebug() << "OAuth2::onDeviceAuthReplyFinished: reply is null"; - return; - } - if (tokenReply->error() == QNetworkReply::NoError) { - QByteArray replyData = tokenReply->readAll(); - - // Dump replyData - // SENSITIVE DATA in RelWithDebInfo or Debug builds - //qDebug() << "OAuth2::onDeviceAuthReplyFinished: replyData\n"; - //qDebug() << QString( replyData ); - - QVariantMap params = parseJsonResponse(replyData); - - // Dump tokens - qDebug() << "OAuth2::onDeviceAuthReplyFinished: Tokens returned:\n"; - foreach (QString key, params.keys()) { - // SENSITIVE DATA in RelWithDebInfo or Debug builds, so it is truncated first - qDebug() << key << ": "<< params.value( key ).toString(); - } - - // Check for mandatory parameters - if (hasMandatoryDeviceAuthParams(params)) { - qDebug() << "OAuth2::onDeviceAuthReplyFinished: Device auth request response"; - - const QString userCode = params.take(OAUTH2_USER_CODE).toString(); - QUrl uri = params.take(OAUTH2_VERIFICATION_URI).toUrl(); - if (uri.isEmpty()) - uri = params.take(OAUTH2_VERIFICATION_URL).toUrl(); - - if (params.contains(OAUTH2_VERIFICATION_URI_COMPLETE)) - emit openBrowser(params.take(OAUTH2_VERIFICATION_URI_COMPLETE).toUrl()); - - bool ok = false; - int expiresIn = params[OAUTH2_EXPIRES_IN].toInt(&ok); - if (!ok) { - qWarning() << "OAuth2::startPollServer: No expired_in parameter"; - emit linkingFailed(); - return; - } - - emit showVerificationUriAndCode(uri, userCode, expiresIn); - - startPollServer(params, expiresIn); - } else { - qWarning() << "OAuth2::onDeviceAuthReplyFinished: Mandatory parameters missing from response"; - emit linkingFailed(); - updateActivity(Activity::Idle); - } - } - tokenReply->deleteLater(); -} - -void OAuth2::serverHasClosed(bool paramsfound) -{ - if ( !paramsfound ) { - // server has probably timed out after receiving first response - emit linkingFailed(); - } - // poll server is not re-used for later auth requests - setPollServer(NULL); -} - -QString OAuth2::apiKey() { - return apiKey_; -} - -void OAuth2::setApiKey(const QString &value) { - apiKey_ = value; -} - -bool OAuth2::ignoreSslErrors() { - return timedReplies_.ignoreSslErrors(); -} - -void OAuth2::setIgnoreSslErrors(bool ignoreSslErrors) { - timedReplies_.setIgnoreSslErrors(ignoreSslErrors); -} - -} diff --git a/libraries/katabasis/src/Reply.cpp b/libraries/katabasis/src/Reply.cpp index 775b9202..3e27a7e6 100644 --- a/libraries/katabasis/src/Reply.cpp +++ b/libraries/katabasis/src/Reply.cpp @@ -7,25 +7,28 @@ namespace Katabasis { Reply::Reply(QNetworkReply *r, int timeOut, QObject *parent): QTimer(parent), reply(r) { setSingleShot(true); - connect(this, SIGNAL(error(QNetworkReply::NetworkError)), reply, SIGNAL(error(QNetworkReply::NetworkError)), Qt::QueuedConnection); - connect(this, SIGNAL(timeout()), this, SLOT(onTimeOut()), Qt::QueuedConnection); + connect(this, &Reply::timeout, this, &Reply::onTimeOut, Qt::QueuedConnection); start(timeOut); } void Reply::onTimeOut() { - emit error(QNetworkReply::TimeoutError); + timedOut = true; + reply->abort(); } +// ---------------------------- + ReplyList::~ReplyList() { foreach (Reply *timedReply, replies_) { delete timedReply; } } -void ReplyList::add(QNetworkReply *reply) { - if (reply && ignoreSslErrors()) - reply->ignoreSslErrors(); - add(new Reply(reply)); +void ReplyList::add(QNetworkReply *reply, int timeOut) { + if (reply && ignoreSslErrors()) { + reply->ignoreSslErrors(); + } + add(new Reply(reply, timeOut)); } void ReplyList::add(Reply *reply) { diff --git a/libraries/katabasis/src/ReplyServer.cpp b/libraries/katabasis/src/ReplyServer.cpp deleted file mode 100755 index 4598b18a..00000000 --- a/libraries/katabasis/src/ReplyServer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include <QTcpServer> -#include <QTcpSocket> -#include <QByteArray> -#include <QString> -#include <QMap> -#include <QPair> -#include <QTimer> -#include <QStringList> -#include <QUrl> -#include <QDebug> -#include <QUrlQuery> - -#include "katabasis/Globals.h" -#include "katabasis/ReplyServer.h" - -namespace Katabasis { - -ReplyServer::ReplyServer(QObject *parent): QTcpServer(parent), - timeout_(15), maxtries_(3), tries_(0) { - qDebug() << "O2ReplyServer: Starting"; - connect(this, SIGNAL(newConnection()), this, SLOT(onIncomingConnection())); - replyContent_ = "<HTML></HTML>"; -} - -void ReplyServer::onIncomingConnection() { - qDebug() << "O2ReplyServer::onIncomingConnection: Receiving..."; - QTcpSocket *socket = nextPendingConnection(); - connect(socket, SIGNAL(readyRead()), this, SLOT(onBytesReady()), Qt::UniqueConnection); - connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); - - // Wait for a bit *after* first response, then close server if no useable data has arrived - // Helps with implicit flow, where a URL fragment may need processed by local user-agent and - // sent as secondary query string callback, or additional requests make it through first, - // like for favicons, etc., before such secondary callbacks are fired - QTimer *timer = new QTimer(socket); - timer->setObjectName("timeoutTimer"); - connect(timer, SIGNAL(timeout()), this, SLOT(closeServer())); - timer->setSingleShot(true); - timer->setInterval(timeout() * 1000); - connect(socket, SIGNAL(readyRead()), timer, SLOT(start())); -} - -void ReplyServer::onBytesReady() { - if (!isListening()) { - // server has been closed, stop processing queued connections - return; - } - qDebug() << "O2ReplyServer::onBytesReady: Processing request"; - // NOTE: on first call, the timeout timer is started - QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); - if (!socket) { - qWarning() << "O2ReplyServer::onBytesReady: No socket available"; - return; - } - QByteArray reply; - reply.append("HTTP/1.0 200 OK \r\n"); - reply.append("Content-Type: text/html; charset=\"utf-8\"\r\n"); - reply.append(QString("Content-Length: %1\r\n\r\n").arg(replyContent_.size()).toLatin1()); - reply.append(replyContent_); - socket->write(reply); - qDebug() << "O2ReplyServer::onBytesReady: Sent reply"; - - QByteArray data = socket->readAll(); - QMap<QString, QString> queryParams = parseQueryParams(&data); - if (queryParams.isEmpty()) { - if (tries_ < maxtries_ ) { - qDebug() << "O2ReplyServer::onBytesReady: No query params found, waiting for more callbacks"; - ++tries_; - return; - } else { - tries_ = 0; - qWarning() << "O2ReplyServer::onBytesReady: No query params found, maximum callbacks received"; - closeServer(socket, false); - return; - } - } - if (!uniqueState_.isEmpty() && !queryParams.contains(QString(OAUTH2_STATE))) { - qDebug() << "O2ReplyServer::onBytesReady: Malicious or service request"; - closeServer(socket, true); - return; // Malicious or service (e.g. favicon.ico) request - } - qDebug() << "O2ReplyServer::onBytesReady: Query params found, closing server"; - closeServer(socket, true); - emit verificationReceived(queryParams); -} - -QMap<QString, QString> ReplyServer::parseQueryParams(QByteArray *data) { - qDebug() << "O2ReplyServer::parseQueryParams"; - - //qDebug() << QString("O2ReplyServer::parseQueryParams data:\n%1").arg(QString(*data)); - - QString splitGetLine = QString(*data).split("\r\n").first(); - splitGetLine.remove("GET "); - splitGetLine.remove("HTTP/1.1"); - splitGetLine.remove("\r\n"); - splitGetLine.prepend("http://localhost"); - QUrl getTokenUrl(splitGetLine); - - QList< QPair<QString, QString> > tokens; - QUrlQuery query(getTokenUrl); - tokens = query.queryItems(); - QMap<QString, QString> queryParams; - QPair<QString, QString> tokenPair; - foreach (tokenPair, tokens) { - // FIXME: We are decoding key and value again. This helps with Google OAuth, but is it mandated by the standard? - QString key = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.first.trimmed().toLatin1())); - QString value = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.second.trimmed().toLatin1())); - queryParams.insert(key, value); - } - return queryParams; -} - -void ReplyServer::closeServer(QTcpSocket *socket, bool hasparameters) -{ - if (!isListening()) { - return; - } - - qDebug() << "O2ReplyServer::closeServer: Initiating"; - int port = serverPort(); - - if (!socket && sender()) { - QTimer *timer = qobject_cast<QTimer*>(sender()); - if (timer) { - qWarning() << "O2ReplyServer::closeServer: Closing due to timeout"; - timer->stop(); - socket = qobject_cast<QTcpSocket *>(timer->parent()); - timer->deleteLater(); - } - } - if (socket) { - QTimer *timer = socket->findChild<QTimer*>("timeoutTimer"); - if (timer) { - qDebug() << "O2ReplyServer::closeServer: Stopping socket's timeout timer"; - timer->stop(); - } - socket->disconnectFromHost(); - } - close(); - qDebug() << "O2ReplyServer::closeServer: Closed, no longer listening on port" << port; - emit serverClosed(hasparameters); -} - -QByteArray ReplyServer::replyContent() { - return replyContent_; -} - -void ReplyServer::setReplyContent(const QByteArray &value) { - replyContent_ = value; -} - -int ReplyServer::timeout() -{ - return timeout_; -} - -void ReplyServer::setTimeout(int timeout) -{ - timeout_ = timeout; -} - -int ReplyServer::callbackTries() -{ - return maxtries_; -} - -void ReplyServer::setCallbackTries(int maxtries) -{ - maxtries_ = maxtries; -} - -QString ReplyServer::uniqueState() -{ - return uniqueState_; -} - -void ReplyServer::setUniqueState(const QString &state) -{ - uniqueState_ = state; -} - -} |