aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp (renamed from launcher/Launcher.cpp)329
-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.h5
-rw-r--r--launcher/BaseVersionList.h2
-rw-r--r--launcher/CMakeLists.txt591
-rw-r--r--launcher/ColumnResizer.cpp199
-rw-r--r--launcher/ColumnResizer.h41
-rw-r--r--launcher/Env.cpp210
-rw-r--r--launcher/Env.h63
-rw-r--r--launcher/InstanceImportTask.cpp17
-rw-r--r--launcher/InstanceImportTask.h2
-rw-r--r--launcher/InstancePageProvider.h34
-rw-r--r--launcher/JavaCommon.cpp2
-rw-r--r--launcher/LaunchController.cpp241
-rw-r--r--launcher/NullInstance.h3
-rw-r--r--launcher/QObjectPtr.h6
-rw-r--r--launcher/SkinUtils.cpp4
-rw-r--r--launcher/Usable.h10
-rw-r--r--launcher/VersionProxyModel.cpp8
-rw-r--r--launcher/icons/IIconList.cpp7
-rw-r--r--launcher/icons/IIconList.h25
-rw-r--r--launcher/icons/IconList.h23
-rw-r--r--launcher/icons/MMCIcon.h10
-rw-r--r--launcher/java/JavaChecker.cpp12
-rw-r--r--launcher/java/JavaInstallList.cpp4
-rw-r--r--launcher/java/JavaInstallList.h4
-rw-r--r--launcher/java/JavaUtils.cpp19
-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.h2
-rw-r--r--launcher/main.cpp16
-rw-r--r--launcher/meta/BaseEntity.cpp20
-rw-r--r--launcher/meta/BaseEntity.h6
-rw-r--r--launcher/meta/Index_test.cpp7
-rw-r--r--launcher/meta/VersionList.cpp2
-rw-r--r--launcher/meta/VersionList.h2
-rw-r--r--launcher/minecraft/AssetsUtils.cpp4
-rw-r--r--launcher/minecraft/AssetsUtils.h4
-rw-r--r--launcher/minecraft/Component.cpp18
-rw-r--r--launcher/minecraft/ComponentUpdateTask.cpp33
-rw-r--r--launcher/minecraft/Library.cpp5
-rw-r--r--launcher/minecraft/Library.h2
-rw-r--r--launcher/minecraft/Library_test.cpp2
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp48
-rw-r--r--launcher/minecraft/MinecraftInstance.h4
-rw-r--r--launcher/minecraft/MinecraftLoadAndCheck.h2
-rw-r--r--launcher/minecraft/MinecraftUpdate.cpp1
-rw-r--r--launcher/minecraft/PackProfile.cpp23
-rw-r--r--launcher/minecraft/PackProfile.h2
-rw-r--r--launcher/minecraft/PackProfile_p.h2
-rw-r--r--launcher/minecraft/VersionFilterData.cpp1
-rw-r--r--launcher/minecraft/VersionFilterData.h2
-rw-r--r--launcher/minecraft/auth/AccountData.cpp49
-rw-r--r--launcher/minecraft/auth/AccountData.h24
-rw-r--r--launcher/minecraft/auth/AccountList.cpp314
-rw-r--r--launcher/minecraft/auth/AccountList.h52
-rw-r--r--launcher/minecraft/auth/AccountTask.cpp79
-rw-r--r--launcher/minecraft/auth/AccountTask.h72
-rw-r--r--launcher/minecraft/auth/AuthRequest.cpp (renamed from launcher/minecraft/auth/flows/AuthRequest.cpp)16
-rw-r--r--launcher/minecraft/auth/AuthRequest.h (renamed from launcher/minecraft/auth/flows/AuthRequest.h)9
-rw-r--r--launcher/minecraft/auth/AuthSession.h4
-rw-r--r--launcher/minecraft/auth/AuthStep.cpp7
-rw-r--r--launcher/minecraft/auth/AuthStep.h33
-rw-r--r--launcher/minecraft/auth/MinecraftAccount.cpp272
-rw-r--r--launcher/minecraft/auth/MinecraftAccount.h56
-rw-r--r--launcher/minecraft/auth/Parsers.cpp316
-rw-r--r--launcher/minecraft/auth/Parsers.h19
-rw-r--r--launcher/minecraft/auth/Yggdrasil.cpp (renamed from launcher/minecraft/auth/flows/Yggdrasil.cpp)106
-rw-r--r--launcher/minecraft/auth/Yggdrasil.h (renamed from launcher/minecraft/auth/flows/Yggdrasil.h)28
-rw-r--r--launcher/minecraft/auth/flows/AuthContext.cpp911
-rw-r--r--launcher/minecraft/auth/flows/AuthContext.h107
-rw-r--r--launcher/minecraft/auth/flows/AuthFlow.cpp71
-rw-r--r--launcher/minecraft/auth/flows/AuthFlow.h45
-rw-r--r--launcher/minecraft/auth/flows/MSA.cpp37
-rw-r--r--launcher/minecraft/auth/flows/MSA.h22
-rw-r--r--launcher/minecraft/auth/flows/MSAInteractive.cpp20
-rw-r--r--launcher/minecraft/auth/flows/MSAInteractive.h10
-rw-r--r--launcher/minecraft/auth/flows/MSASilent.cpp16
-rw-r--r--launcher/minecraft/auth/flows/MSASilent.h10
-rw-r--r--launcher/minecraft/auth/flows/Mojang.cpp27
-rw-r--r--launcher/minecraft/auth/flows/Mojang.h26
-rw-r--r--launcher/minecraft/auth/flows/MojangLogin.cpp14
-rw-r--r--launcher/minecraft/auth/flows/MojangLogin.h13
-rw-r--r--launcher/minecraft/auth/flows/MojangRefresh.cpp14
-rw-r--r--launcher/minecraft/auth/flows/MojangRefresh.h10
-rw-r--r--launcher/minecraft/auth/steps/EntitlementsStep.cpp53
-rw-r--r--launcher/minecraft/auth/steps/EntitlementsStep.h25
-rw-r--r--launcher/minecraft/auth/steps/GetSkinStep.cpp43
-rw-r--r--launcher/minecraft/auth/steps/GetSkinStep.h22
-rw-r--r--launcher/minecraft/auth/steps/LauncherLoginStep.cpp78
-rw-r--r--launcher/minecraft/auth/steps/LauncherLoginStep.h22
-rw-r--r--launcher/minecraft/auth/steps/MSAStep.cpp111
-rw-r--r--launcher/minecraft/auth/steps/MSAStep.h32
-rw-r--r--launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp45
-rw-r--r--launcher/minecraft/auth/steps/MigrationEligibilityStep.h22
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStep.cpp83
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStep.h22
-rw-r--r--launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp158
-rw-r--r--launcher/minecraft/auth/steps/XboxAuthorizationStep.h34
-rw-r--r--launcher/minecraft/auth/steps/XboxProfileStep.cpp73
-rw-r--r--launcher/minecraft/auth/steps/XboxProfileStep.h22
-rw-r--r--launcher/minecraft/auth/steps/XboxUserStep.cpp68
-rw-r--r--launcher/minecraft/auth/steps/XboxUserStep.h22
-rw-r--r--launcher/minecraft/auth/steps/YggdrasilStep.cpp51
-rw-r--r--launcher/minecraft/auth/steps/YggdrasilStep.h28
-rw-r--r--launcher/minecraft/launch/ClaimAccount.cpp6
-rw-r--r--launcher/minecraft/launch/LauncherPartLaunch.cpp15
-rw-r--r--launcher/minecraft/launch/VerifyJavaInstall.cpp11
-rw-r--r--launcher/minecraft/legacy/LegacyInstance.cpp12
-rw-r--r--launcher/minecraft/legacy/LegacyInstance.h8
-rw-r--r--launcher/minecraft/services/CapeChange.cpp20
-rw-r--r--launcher/minecraft/services/CapeChange.h8
-rw-r--r--launcher/minecraft/services/SkinDelete.cpp14
-rw-r--r--launcher/minecraft/services/SkinDelete.h11
-rw-r--r--launcher/minecraft/services/SkinUpload.cpp14
-rw-r--r--launcher/minecraft/services/SkinUpload.h9
-rw-r--r--launcher/minecraft/update/AssetUpdateTask.cpp12
-rw-r--r--launcher/minecraft/update/AssetUpdateTask.h2
-rw-r--r--launcher/minecraft/update/FMLLibrariesTask.cpp14
-rw-r--r--launcher/minecraft/update/FMLLibrariesTask.h2
-rw-r--r--launcher/minecraft/update/LibrariesTask.cpp8
-rw-r--r--launcher/minecraft/update/LibrariesTask.h2
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.cpp39
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.h2
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.cpp8
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.h5
-rw-r--r--launcher/modplatform/legacy_ftb/PackFetchTask.cpp18
-rw-r--r--launcher/modplatform/legacy_ftb/PackFetchTask.h5
-rw-r--r--launcher/modplatform/legacy_ftb/PackInstallTask.cpp26
-rw-r--r--launcher/modplatform/legacy_ftb/PackInstallTask.h7
-rw-r--r--launcher/modplatform/modpacksch/FTBPackInstallTask.cpp13
-rw-r--r--launcher/modplatform/modpacksch/FTBPackInstallTask.h2
-rw-r--r--launcher/modplatform/technic/SingleZipPackInstallTask.cpp11
-rw-r--r--launcher/modplatform/technic/SingleZipPackInstallTask.h2
-rw-r--r--launcher/modplatform/technic/SolderPackInstallTask.cpp14
-rw-r--r--launcher/modplatform/technic/SolderPackInstallTask.h6
-rw-r--r--launcher/net/Download.cpp19
-rw-r--r--launcher/net/Download.h6
-rw-r--r--launcher/net/FileSink.cpp1
-rw-r--r--launcher/net/HttpMetaCache.cpp1
-rw-r--r--launcher/net/MetaCacheSink.cpp4
-rw-r--r--launcher/net/NetAction.h15
-rw-r--r--launcher/net/NetJob.cpp4
-rw-r--r--launcher/net/NetJob.h30
-rw-r--r--launcher/net/PasteUpload.cpp7
-rw-r--r--launcher/news/NewsChecker.cpp5
-rw-r--r--launcher/news/NewsChecker.h6
-rw-r--r--launcher/notifications/NotificationChecker.cpp6
-rw-r--r--launcher/notifications/NotificationChecker.h2
-rw-r--r--launcher/resources/backgrounds/backgrounds.qrc1
-rw-r--r--launcher/resources/backgrounds/cattiversary.pngbin0 -> 99736 bytes
-rw-r--r--launcher/resources/sources/burfcat_hat.pngbin0 -> 15813 bytes
-rw-r--r--launcher/resources/sources/cattiversary.xcfbin0 -> 121675 bytes
-rw-r--r--launcher/screenshots/ImgurAlbumCreation.cpp10
-rw-r--r--launcher/screenshots/ImgurAlbumCreation.h11
-rw-r--r--launcher/screenshots/ImgurUpload.cpp10
-rw-r--r--launcher/screenshots/ImgurUpload.h28
-rw-r--r--launcher/screenshots/Screenshot.h10
-rw-r--r--launcher/tasks/SequentialTask.cpp6
-rw-r--r--launcher/tasks/SequentialTask.h6
-rw-r--r--launcher/tasks/Task.h4
-rw-r--r--launcher/translations/TranslationsModel.cpp42
-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)356
-rw-r--r--launcher/ui/MainWindow.h (renamed from launcher/MainWindow.h)6
-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)2
-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)2
-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.cpp256
-rw-r--r--launcher/ui/dialogs/ProfileSetupDialog.h88
-rw-r--r--launcher/ui/dialogs/ProfileSetupDialog.ui74
-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)20
-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)69
-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)52
-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/ErrorFrame.cpp134
-rw-r--r--launcher/ui/widgets/ErrorFrame.h49
-rw-r--r--launcher/ui/widgets/ErrorFrame.ui92
-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.cpp14
-rw-r--r--launcher/updater/DownloadTask.h9
-rw-r--r--launcher/updater/GoUpdate.cpp2
-rw-r--r--launcher/updater/GoUpdate.h2
-rw-r--r--launcher/updater/UpdateChecker.cpp38
-rw-r--r--launcher/updater/UpdateChecker.h8
-rw-r--r--launcher/updater/UpdateChecker_test.cpp6
406 files changed, 4995 insertions, 3755 deletions
diff --git a/launcher/Launcher.cpp b/launcher/Application.cpp
index a69fb8f3..2d0c81bb 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.";
}
@@ -815,26 +827,34 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv)
qDebug() << "Loading accounts...";
m_accounts->setListFilePath("accounts.json", true);
m_accounts->loadList();
+ m_accounts->fillQueue();
qDebug() << "<> Accounts loaded.";
}
// 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 +871,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 +901,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 +913,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 +938,7 @@ Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv)
performMainStartupAction();
}
-bool Launcher::createSetupWizard()
+bool Application::createSetupWizard()
{
bool javaRequired = [&]()
{
@@ -975,22 +996,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 +1054,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 +1078,7 @@ Launcher::~Launcher()
#endif
}
-void Launcher::messageReceived(const QByteArray& message)
+void Application::messageReceived(const QByteArray& message)
{
if(status() != Initialized)
{
@@ -1068,7 +1086,7 @@ void Launcher::messageReceived(const QByteArray& message)
return;
}
- LauncherMessage received;
+ ApplicationMessage received;
received.parse(message);
auto & command = received.command;
@@ -1134,7 +1152,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 +1168,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 +1182,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 +1194,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 +1209,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 +1222,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 +1236,7 @@ bool Launcher::openJsonEditor(const QString &filename)
}
}
-bool Launcher::launch(
+bool Application::launch(
InstancePtr instance,
bool online,
BaseProfilerFactory *profiler,
@@ -1255,8 +1273,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 +1292,7 @@ bool Launcher::launch(
return false;
}
-bool Launcher::kill(InstancePtr instance)
+bool Application::kill(InstancePtr instance)
{
if (!instance->isRunning())
{
@@ -1291,7 +1309,7 @@ bool Launcher::kill(InstancePtr instance)
return true;
}
-void Launcher::addRunningInstance()
+void Application::addRunningInstance()
{
m_runningInstances ++;
if(m_runningInstances == 1)
@@ -1300,7 +1318,7 @@ void Launcher::addRunningInstance()
}
}
-void Launcher::subRunningInstance()
+void Application::subRunningInstance()
{
if(m_runningInstances == 0)
{
@@ -1314,23 +1332,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 +1375,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 +1396,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 +1421,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 +1433,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 +1494,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 +1511,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 +1524,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 +1548,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..488f2781 100644
--- a/launcher/BaseInstance.h
+++ b/launcher/BaseInstance.h
@@ -100,6 +100,9 @@ public:
return instanceRoot();
}
+ /// Path to the instance's mods directory.
+ virtual QString modsRoot() const = 0;
+
QString name() const;
void setName(QString val);
@@ -143,7 +146,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..2dfc78b5 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
)
@@ -200,33 +196,52 @@ set(ICONS_SOURCES
# Support for Minecraft instances and launch
set(MINECRAFT_SOURCES
# Minecraft support
- minecraft/auth/AccountData.h
minecraft/auth/AccountData.cpp
- minecraft/auth/AccountTask.h
+ minecraft/auth/AccountData.h
+ minecraft/auth/AccountList.cpp
+ minecraft/auth/AccountList.h
minecraft/auth/AccountTask.cpp
- minecraft/auth/AuthSession.h
+ minecraft/auth/AccountTask.h
+ minecraft/auth/AuthRequest.cpp
+ minecraft/auth/AuthRequest.h
minecraft/auth/AuthSession.cpp
- minecraft/auth/AccountList.h
- minecraft/auth/AccountList.cpp
- minecraft/auth/MinecraftAccount.h
+ minecraft/auth/AuthSession.h
+ minecraft/auth/AuthStep.cpp
+ minecraft/auth/AuthStep.h
minecraft/auth/MinecraftAccount.cpp
- minecraft/auth/flows/AuthContext.h
- minecraft/auth/flows/AuthContext.cpp
- minecraft/auth/flows/AuthRequest.h
- minecraft/auth/flows/AuthRequest.cpp
-
- minecraft/auth/flows/MSAInteractive.h
- minecraft/auth/flows/MSAInteractive.cpp
- minecraft/auth/flows/MSASilent.h
- minecraft/auth/flows/MSASilent.cpp
-
- minecraft/auth/flows/MojangLogin.h
- minecraft/auth/flows/MojangLogin.cpp
- minecraft/auth/flows/MojangRefresh.h
- minecraft/auth/flows/MojangRefresh.cpp
-
- minecraft/auth/flows/Yggdrasil.h
- minecraft/auth/flows/Yggdrasil.cpp
+ minecraft/auth/MinecraftAccount.h
+ minecraft/auth/Parsers.cpp
+ minecraft/auth/Parsers.h
+ minecraft/auth/Yggdrasil.cpp
+ minecraft/auth/Yggdrasil.h
+
+ minecraft/auth/flows/AuthFlow.cpp
+ minecraft/auth/flows/AuthFlow.h
+ minecraft/auth/flows/Mojang.cpp
+ minecraft/auth/flows/Mojang.h
+ minecraft/auth/flows/MSA.cpp
+ minecraft/auth/flows/MSA.h
+
+ minecraft/auth/steps/EntitlementsStep.cpp
+ minecraft/auth/steps/EntitlementsStep.h
+ minecraft/auth/steps/GetSkinStep.cpp
+ minecraft/auth/steps/GetSkinStep.h
+ minecraft/auth/steps/LauncherLoginStep.cpp
+ minecraft/auth/steps/LauncherLoginStep.h
+ minecraft/auth/steps/MigrationEligibilityStep.cpp
+ minecraft/auth/steps/MigrationEligibilityStep.h
+ minecraft/auth/steps/MinecraftProfileStep.cpp
+ minecraft/auth/steps/MinecraftProfileStep.h
+ minecraft/auth/steps/MSAStep.cpp
+ minecraft/auth/steps/MSAStep.h
+ minecraft/auth/steps/XboxAuthorizationStep.cpp
+ minecraft/auth/steps/XboxAuthorizationStep.h
+ minecraft/auth/steps/XboxProfileStep.cpp
+ minecraft/auth/steps/XboxProfileStep.h
+ minecraft/auth/steps/XboxUserStep.cpp
+ minecraft/auth/steps/XboxUserStep.h
+ minecraft/auth/steps/YggdrasilStep.cpp
+ minecraft/auth/steps/YggdrasilStep.h
minecraft/gameoptions/GameOptions.h
minecraft/gameoptions/GameOptions.cpp
@@ -422,9 +437,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 +573,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 +611,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 +661,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 +906,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..be12eb79 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)
{
}
@@ -31,6 +35,8 @@ void LaunchController::executeTask()
return;
}
+ JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget);
+
login();
}
@@ -41,7 +47,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 +64,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,15 +85,13 @@ 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);
}
}
}
void LaunchController::login() {
- JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget);
-
decideAccount();
// if no account is selected, we bail
@@ -109,132 +113,118 @@ void LaunchController::login() {
{
m_session = std::make_shared<AuthSession>();
m_session->wants_online = m_online;
- std::shared_ptr<AccountTask> task;
- if(!password.isNull()) {
- task = m_accountToUse->login(m_session, password);
- }
- else {
- task = m_accountToUse->refresh(m_session);
- }
- if (task)
- {
- // We'll need to validate the access token to make sure the account
- // is still logged in.
- ProgressDialog progDialog(m_parentWidget);
- if (m_online)
- {
- progDialog.setSkipButton(true, tr("Play Offline"));
+ m_accountToUse->fillSession(m_session);
+
+ switch(m_accountToUse->accountState()) {
+ case AccountState::Offline: {
+ m_session->wants_online = false;
+ // NOTE: fallthrough is intentional
}
- progDialog.execWithTask(task.get());
- if (!task->wasSuccessful())
- {
- auto failReasonNew = task->failReason();
- if(failReasonNew == "Invalid token." || failReasonNew == "Invalid Signature")
- {
- // account->invalidateClientToken();
- failReason = needLoginAgain;
+ case AccountState::Online: {
+ if(!m_session->wants_online) {
+ // we ask the user for a player name
+ bool ok = false;
+ QString usedname = m_session->player_name;
+ QString name = QInputDialog::getText(
+ m_parentWidget,
+ tr("Player name"),
+ tr("Choose your offline mode player name."),
+ QLineEdit::Normal,
+ m_session->player_name,
+ &ok
+ );
+ if (!ok)
+ {
+ tryagain = false;
+ break;
+ }
+ if (name.length())
+ {
+ usedname = name;
+ }
+ m_session->MakeOffline(usedname);
+ // offline flavored game from here :3
}
- else failReason = failReasonNew;
- }
- }
- switch (m_session->status)
- {
- case AuthSession::Undetermined: {
- qCritical() << "Received undetermined session status during login. Bye.";
- tryagain = false;
- emitFailed(tr("Received undetermined session status during login."));
- return;
- }
- case AuthSession::RequiresPassword: {
- // FIXME: this needs to understand MSA
- EditAccountDialog passDialog(failReason, m_parentWidget, EditAccountDialog::PasswordField);
- auto username = m_session->username;
- auto chopN = [](QString toChop, int N) -> QString
- {
- if(toChop.size() > N)
+ if(m_accountToUse->ownsMinecraft() && !m_accountToUse->hasProfile()) {
+ 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
+ );
+ emitFailed(errorString);
+ return;
+ }
+ // Now handle setting up a profile name here...
+ ProfileSetupDialog dialog(m_accountToUse, m_parentWidget);
+ if (dialog.exec() == QDialog::Accepted)
{
- auto left = toChop.left(N);
- left += QString("\u25CF").repeated(toChop.size() - N);
- return left;
+ tryagain = true;
+ continue;
+ }
+ else
+ {
+ emitFailed(tr("Received undetermined session status during login."));
+ return;
}
- return toChop;
- };
-
- if(username.contains('@'))
- {
- auto parts = username.split('@');
- auto mailbox = chopN(parts[0],3);
- QString domain = chopN(parts[1], 3);
- username = mailbox + '@' + domain;
}
- passDialog.setUsername(username);
- if (passDialog.exec() == QDialog::Accepted)
- {
- password = passDialog.password();
+ else {
+ launchInstance();
}
- else
+ return;
+ }
+ case AccountState::Errored:
+ // This means some sort of soft error that we can fix with a refresh ... so let's refresh.
+ case AccountState::Unchecked: {
+ m_accountToUse->refresh();
+ // NOTE: fallthrough intentional
+ }
+ case AccountState::Working: {
+ // refresh is in progress, we need to wait for it to finish to proceed.
+ ProgressDialog progDialog(m_parentWidget);
+ if (m_online)
{
- tryagain = false;
- emitFailed(tr("Received undetermined session status during login."));
+ progDialog.setSkipButton(true, tr("Play Offline"));
}
- break;
+ auto task = m_accountToUse->currentTask();
+ progDialog.execWithTask(task.get());
+ continue;
}
- case AuthSession::RequiresOAuth: {
- auto errorString = tr("Microsoft account has expired and needs to be logged into manually again.");
+ // FIXME: this is missing - the meaning is that the account is queued for refresh and we should wait for that
+ /*
+ case AccountState::Queued: {
+ return;
+ }
+ */
+ case AccountState::Expired: {
+ auto errorString = tr("The account has expired and needs to be logged into manually again.");
QMessageBox::warning(
- nullptr,
- tr("Microsoft Account refresh failed"),
+ m_parentWidget,
+ tr("Account refresh failed"),
errorString,
QMessageBox::StandardButton::Ok,
QMessageBox::StandardButton::Ok
);
- tryagain = false;
emitFailed(errorString);
return;
}
- case AuthSession::GoneOrMigrated: {
+ case AccountState::Gone: {
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,
QMessageBox::StandardButton::Ok
);
- tryagain = false;
emitFailed(errorString);
return;
}
- case AuthSession::PlayableOffline: {
- // we ask the user for a player name
- bool ok = false;
- QString usedname = m_session->player_name;
- QString name = QInputDialog::getText(
- m_parentWidget,
- tr("Player name"),
- tr("Choose your offline mode player name."),
- QLineEdit::Normal,
- m_session->player_name,
- &ok
- );
- if (!ok)
- {
- tryagain = false;
- break;
- }
- if (name.length())
- {
- usedname = name;
- }
- m_session->MakeOffline(usedname);
- // offline flavored game from here :3
- }
- case AuthSession::PlayableOnline:
- {
- launchInstance();
- tryagain = false;
- return;
- }
}
}
emitFailed(tr("Failed to launch."));
@@ -263,7 +253,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);
@@ -300,14 +290,7 @@ void LaunchController::launchInstance()
online_mode = "offline";
}
- QString auth_server_status;
- if(m_session->auth_server_online) {
- auth_server_status = "online";
- } else {
- auth_server_status = "offline";
- }
-
- m_launcher->prependStep(new TextPrint(m_launcher.get(), "Launched instance in " + online_mode + " mode\nAuthentication server is " + auth_server_status + "\n", MessageLevel::Launcher));
+ m_launcher->prependStep(new TextPrint(m_launcher.get(), "Launched instance in " + online_mode + " mode\n", MessageLevel::Launcher));
// Prepend Version
m_launcher->prependStep(new TextPrint(m_launcher.get(), BuildConfig.LAUNCHER_NAME + " version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::Launcher));
@@ -369,7 +352,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/NullInstance.h b/launcher/NullInstance.h
index 94ed6c3a..ed421433 100644
--- a/launcher/NullInstance.h
+++ b/launcher/NullInstance.h
@@ -73,4 +73,7 @@ public:
out << "Null instance - placeholder.";
return out;
}
+ QString modsRoot() const override {
+ return QString();
+ }
};
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 c00ee710..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);
@@ -386,6 +394,7 @@ QList<QString> JavaUtils::FindJavaPaths()
scanJavaDir("/usr/java");
// general locations used by distro packaging
scanJavaDir("/usr/lib/jvm");
+ scanJavaDir("/usr/lib64/jvm");
scanJavaDir("/usr/lib32/jvm");
// javas stored in MultiMC's folder
scanJavaDir("java");
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..2526e620 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"
@@ -198,7 +202,7 @@ QString MinecraftInstance::jarModsDir() const
return jarmods_dir.absolutePath();
}
-QString MinecraftInstance::loaderModsDir() const
+QString MinecraftInstance::modsRoot() const
{
return FS::PathCombine(gameRoot(), "mods");
}
@@ -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
{
@@ -957,7 +961,7 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::loaderModList() const
{
if (!m_loader_mod_list)
{
- m_loader_mod_list.reset(new ModFolderModel(loaderModsDir()));
+ m_loader_mod_list.reset(new ModFolderModel(modsRoot()));
m_loader_mod_list->disableInteraction(isRunning());
connect(this, &BaseInstance::runningStatusChanged, m_loader_mod_list.get(), &ModFolderModel::disableInteraction);
}
diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h
index b11270e6..fda58aa7 100644
--- a/launcher/minecraft/MinecraftInstance.h
+++ b/launcher/minecraft/MinecraftInstance.h
@@ -40,7 +40,7 @@ public:
QString resourcePacksDir() const;
QString texturePacksDir() const;
QString shaderPacksDir() const;
- QString loaderModsDir() const;
+ QString modsRoot() const override;
QString coreModsDir() const;
QString modsCacheLocation() const;
QString libDir() const;
@@ -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..7526c951 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 {
@@ -397,3 +438,7 @@ QString AccountData::accountDisplayString() const {
}
}
}
+
+QString AccountData::lastError() const {
+ return errorString;
+}
diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h
index cf58fb76..abf84e43 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;
@@ -35,6 +41,16 @@ enum class AccountType {
Mojang
};
+enum class AccountState {
+ Unchecked,
+ Offline,
+ Working,
+ Online,
+ Errored,
+ Expired,
+ Gone
+};
+
struct AccountData {
QJsonObject saveState() const;
bool resumeStateFromV2(QJsonObject data);
@@ -58,6 +74,8 @@ struct AccountData {
QString profileId() const;
QString profileName() const;
+ QString lastError() const;
+
AccountType type = AccountType::MSA;
bool legacy = false;
bool canMigrateToMSA = false;
@@ -69,5 +87,11 @@ struct AccountData {
Katabasis::Token yggdrasilToken;
MinecraftProfile minecraftProfile;
+ MinecraftEntitlement minecraftEntitlement;
Katabasis::Validity validity_ = Katabasis::Validity::None;
+
+ // runtime only information (not saved with the account)
+ QString internalId;
+ QString errorString;
+ AccountState accountState = AccountState::Unchecked;
};
diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp
index a76cac55..ef8b435d 100644
--- a/launcher/minecraft/auth/AccountList.cpp
+++ b/launcher/minecraft/auth/AccountList.cpp
@@ -15,6 +15,7 @@
#include "AccountList.h"
#include "AccountData.h"
+#include "AccountTask.h"
#include <QIODevice>
#include <QFile>
@@ -24,18 +25,30 @@
#include <QJsonObject>
#include <QJsonParseError>
#include <QDir>
+#include <QTimer>
#include <QDebug>
#include <FileSystem.h>
#include <QSaveFile>
+#include <chrono>
+
enum AccountListVersion {
MojangOnly = 2,
MojangMSA = 3
};
-AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { }
+AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) {
+ m_refreshTimer = new QTimer(this);
+ m_refreshTimer->setSingleShot(true);
+ connect(m_refreshTimer, &QTimer::timeout, this, &AccountList::fillQueue);
+ m_nextTimer = new QTimer(this);
+ m_nextTimer->setSingleShot(true);
+ connect(m_nextTimer, &QTimer::timeout, this, &AccountList::tryNext);
+}
+
+AccountList::~AccountList() noexcept {}
int AccountList::findAccountByProfileId(const QString& profileId) const {
for (int i = 0; i < count(); i++) {
@@ -62,28 +75,50 @@ 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()) {
+ // NOTE: Do not allow adding something that's already there
+ if(m_accounts.contains(account)) {
return;
}
+ // hook up notifications for changes in the account
+ connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged);
+ connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged);
+
// 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;
+ auto profileId = account->profileId();
+ if(profileId.size()) {
+ auto existingAccount = findAccountByProfileId(profileId);
+ if(existingAccount != -1) {
+ MinecraftAccountPtr existingAccountPtr = m_accounts[existingAccount];
+ m_accounts[existingAccount] = account;
+ if(m_defaultAccount == existingAccountPtr) {
+ m_defaultAccount = account;
+ }
+ // disconnect notifications for changes in the account being replaced
+ existingAccountPtr->disconnect(this);
+ 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()));
m_accounts.append(account);
endInsertRows();
onListChanged();
@@ -95,11 +130,13 @@ 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();
}
+ account->disconnect(this);
+
beginRemoveRows(QModelIndex(), row, row);
m_accounts.removeAt(index.row());
endRemoveRows();
@@ -107,54 +144,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 +202,29 @@ 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();
+ if(active) {
+ beginActivity();
+ }
+ else {
+ endActivity();
+ }
+ }
+}
+
+
void AccountList::onListChanged()
{
if (m_autosave)
@@ -174,12 +234,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 +271,32 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
return typeStr;
}
+ case StatusColumn: {
+ switch(account->accountState()) {
+ case AccountState::Unchecked: {
+ return tr("Unchecked", "Account status");
+ }
+ case AccountState::Offline: {
+ return tr("Offline", "Account status");
+ }
+ case AccountState::Online: {
+ return tr("Online", "Account status");
+ }
+ case AccountState::Working: {
+ return tr("Working", "Account status");
+ }
+ case AccountState::Errored: {
+ return tr("Errored", "Account status");
+ }
+ case AccountState::Expired: {
+ return tr("Expired", "Account status");
+ }
+ case AccountState::Gone: {
+ return tr("Gone", "Account status");
+ }
+ }
+ }
+
case ProfileNameColumn: {
return account->profileName();
}
@@ -235,13 +321,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 +346,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 +363,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 +399,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 +410,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 +485,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 +501,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 +526,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 +582,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);
@@ -536,10 +627,113 @@ void AccountList::setListFilePath(QString path, bool autosave)
bool AccountList::anyAccountIsValid()
{
- for(auto account:m_accounts)
+ for(auto account: m_accounts)
{
- if(account->accountStatus() != NotVerified)
+ if(account->ownsMinecraft()) {
return true;
+ }
}
return false;
}
+
+void AccountList::fillQueue() {
+
+ if(m_defaultAccount && m_defaultAccount->shouldRefresh()) {
+ auto idToRefresh = m_defaultAccount->internalId();
+ m_refreshQueue.push_back(idToRefresh);
+ qDebug() << "AccountList: Queued default account with internal ID " << idToRefresh << " to refresh first";
+ }
+
+ for(int i = 0; i < count(); i++) {
+ auto account = at(i);
+ if(account == m_defaultAccount) {
+ continue;
+ }
+
+ if(account->shouldRefresh()) {
+ auto idToRefresh = account->internalId();
+ queueRefresh(idToRefresh);
+ }
+ }
+ tryNext();
+}
+
+void AccountList::requestRefresh(QString accountId) {
+ auto index = m_refreshQueue.indexOf(accountId);
+ if(index != -1) {
+ m_refreshQueue.removeAt(index);
+ }
+ m_refreshQueue.push_front(accountId);
+ qDebug() << "AccountList: Pushed account with internal ID " << accountId << " to the front of the queue";
+ if(!isActive()) {
+ tryNext();
+ }
+}
+
+void AccountList::queueRefresh(QString accountId) {
+ if(m_refreshQueue.indexOf(accountId) != -1) {
+ return;
+ }
+ m_refreshQueue.push_back(accountId);
+ qDebug() << "AccountList: Queued account with internal ID " << accountId << " to refresh";
+}
+
+
+void AccountList::tryNext() {
+ while (m_refreshQueue.length()) {
+ auto accountId = m_refreshQueue.front();
+ m_refreshQueue.pop_front();
+ for(int i = 0; i < count(); i++) {
+ auto account = at(i);
+ if(account->internalId() == accountId) {
+ m_currentTask = account->refresh();
+ if(m_currentTask) {
+ connect(m_currentTask.get(), &AccountTask::succeeded, this, &AccountList::authSucceeded);
+ connect(m_currentTask.get(), &AccountTask::failed, this, &AccountList::authFailed);
+ m_currentTask->start();
+ qDebug() << "RefreshSchedule: Processing account " << account->accountDisplayString() << " with internal ID " << accountId;
+ return;
+ }
+ }
+ }
+ qDebug() << "RefreshSchedule: Account with with internal ID " << accountId << " not found.";
+ }
+ // if we get here, no account needed refreshing. Schedule refresh in an hour.
+ m_refreshTimer->start(1000 * 3600);
+}
+
+void AccountList::authSucceeded() {
+ qDebug() << "RefreshSchedule: Background account refresh succeeded";
+ m_currentTask.reset();
+ m_nextTimer->start(1000 * 20);
+}
+
+void AccountList::authFailed(QString reason) {
+ qDebug() << "RefreshSchedule: Background account refresh failed: " << reason;
+ m_currentTask.reset();
+ m_nextTimer->start(1000 * 20);
+}
+
+bool AccountList::isActive() const {
+ return m_activityCount != 0;
+}
+
+void AccountList::beginActivity() {
+ bool activating = m_activityCount == 0;
+ m_activityCount++;
+ if(activating) {
+ emit activityChanged(true);
+ }
+}
+
+void AccountList::endActivity() {
+ if(m_activityCount == 0) {
+ qWarning() << m_name << " - Activity count would become below zero";
+ return;
+ }
+ bool deactivating = m_activityCount == 1;
+ m_activityCount--;
+ if(deactivating) {
+ emit activityChanged(false);
+ }
+}
diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h
index e275eb17..fa1e7431 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,12 @@ public:
void removeAccount(QModelIndex index);
int findAccountByProfileId(const QString &profileId) const;
MinecraftAccountPtr getAccountByProfileName(const QString &profileName) const;
+ QStringList profileNames() const;
+
+ // requesting a refresh pushes it to the front of the queue
+ void requestRefresh(QString accountId);
+ // queuing a refresh will let it go to the back of the queue (unless it's somewhere inside the queue already)
+ void queueRefresh(QString accountId);
/*!
* Sets the path to load/save the list file from/to.
@@ -78,13 +86,24 @@ public:
bool loadV3(QJsonObject &root);
bool saveList();
- MinecraftAccountPtr activeAccount() const;
- void setActiveAccount(const QString &profileId);
+ MinecraftAccountPtr defaultAccount() const;
+ void setDefaultAccount(MinecraftAccountPtr profileId);
bool anyAccountIsValid();
+ bool isActive() const;
+
+protected:
+ void beginActivity();
+ void endActivity();
+
+private:
+ const char* m_name;
+ uint32_t m_activityCount = 0;
signals:
void listChanged();
- void activeAccountChanged();
+ void listActivityChanged();
+ void defaultAccountChanged();
+ void activityChanged(bool active);
public slots:
/**
@@ -92,7 +111,28 @@ public slots:
*/
void accountChanged();
+ /**
+ * This is called when a (refresh/login) task involving the account starts or ends
+ */
+ void accountActivityChanged(bool active);
+
+ /**
+ * This is initially to run background account refresh tasks, or on a hourly timer
+ */
+ void fillQueue();
+
+private slots:
+ void tryNext();
+
+ void authSucceeded();
+ void authFailed(QString reason);
+
protected:
+ QList<QString> m_refreshQueue;
+ QTimer *m_refreshTimer;
+ QTimer *m_nextTimer;
+ shared_qobject_ptr<AccountTask> m_currentTask;
+
/*!
* Called whenever the list changes.
* This emits the listChanged() signal and autosaves the list (if autosave is enabled).
@@ -101,13 +141,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..98d8d94d 100644
--- a/launcher/minecraft/auth/AccountTask.cpp
+++ b/launcher/minecraft/auth/AccountTask.cpp
@@ -23,49 +23,84 @@
#include <QNetworkReply>
#include <QByteArray>
-#include <Env.h>
-
-#include <BuildConfig.h>
-
#include <QDebug>
AccountTask::AccountTask(AccountData *data, QObject *parent)
: Task(parent), m_data(data)
{
- changeState(STATE_CREATED);
+ changeState(AccountTaskState::STATE_CREATED);
}
QString AccountTask::getStateMessage() const
{
- switch (m_accountState)
+ switch (m_taskState)
{
- case STATE_CREATED:
+ case AccountTaskState::STATE_CREATED:
return "Waiting...";
- case STATE_WORKING:
+ case AccountTaskState::STATE_WORKING:
return tr("Sending request to auth servers...");
- case STATE_SUCCEEDED:
+ case AccountTaskState::STATE_SUCCEEDED:
return tr("Authentication task succeeded.");
- case STATE_FAILED_SOFT:
+ case AccountTaskState::STATE_OFFLINE:
return tr("Failed to contact the authentication server.");
- case STATE_FAILED_HARD:
- return tr("Failed to authenticate.");
- case STATE_FAILED_GONE:
+ case AccountTaskState::STATE_FAILED_SOFT:
+ return tr("Encountered an error during authentication.");
+ case AccountTaskState::STATE_FAILED_HARD:
+ return tr("Failed to authenticate. The session has expired.");
+ case AccountTaskState::STATE_FAILED_GONE:
return tr("Failed to authenticate. The account no longer exists.");
default:
return tr("...");
}
}
-void AccountTask::changeState(AccountTask::State newState, QString reason)
+bool AccountTask::changeState(AccountTaskState newState, QString reason)
{
- m_accountState = newState;
+ m_taskState = newState;
setStatus(getStateMessage());
- if (newState == STATE_SUCCEEDED)
- {
- emitSucceeded();
- }
- else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT || newState == STATE_FAILED_GONE)
- {
- emitFailed(reason);
+ switch(newState) {
+ case AccountTaskState::STATE_CREATED: {
+ m_data->errorString.clear();
+ return true;
+ }
+ case AccountTaskState::STATE_WORKING: {
+ m_data->accountState = AccountState::Working;
+ return true;
+ }
+ case AccountTaskState::STATE_SUCCEEDED: {
+ m_data->accountState = AccountState::Online;
+ emitSucceeded();
+ return false;
+ }
+ case AccountTaskState::STATE_OFFLINE: {
+ m_data->errorString = reason;
+ m_data->accountState = AccountState::Offline;
+ emitFailed(reason);
+ return false;
+ }
+ case AccountTaskState::STATE_FAILED_SOFT: {
+ m_data->errorString = reason;
+ m_data->accountState = AccountState::Errored;
+ emitFailed(reason);
+ return false;
+ }
+ case AccountTaskState::STATE_FAILED_HARD: {
+ m_data->errorString = reason;
+ m_data->accountState = AccountState::Expired;
+ emitFailed(reason);
+ return false;
+ }
+ case AccountTaskState::STATE_FAILED_GONE: {
+ m_data->errorString = reason;
+ m_data->accountState = AccountState::Gone;
+ emitFailed(reason);
+ return false;
+ }
+ default: {
+ QString error = tr("Unknown account task state: %1").arg(int(newState));
+ m_data->accountState = AccountState::Errored;
+ emitFailed(error);
+ return false;
+ }
}
}
diff --git a/launcher/minecraft/auth/AccountTask.h b/launcher/minecraft/auth/AccountTask.h
index 4f3bd52a..dac3f1b5 100644
--- a/launcher/minecraft/auth/AccountTask.h
+++ b/launcher/minecraft/auth/AccountTask.h
@@ -26,62 +26,32 @@
class QNetworkReply;
+/**
+ * Enum for describing the state of the current task.
+ * Used by the getStateMessage function to determine what the status message should be.
+ */
+enum class AccountTaskState
+{
+ STATE_CREATED,
+ STATE_WORKING,
+ STATE_SUCCEEDED,
+ STATE_FAILED_SOFT, //!< soft failure. authentication went through partially
+ STATE_FAILED_HARD, //!< hard failure. main tokens are invalid
+ STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists
+ STATE_OFFLINE //!< soft failure. authentication failed in the first step in a 'soft' way
+};
+
class AccountTask : public Task
{
- friend class AuthContext;
Q_OBJECT
public:
explicit AccountTask(AccountData * data, QObject *parent = 0);
virtual ~AccountTask() {};
- /**
- * assign a session to this task. the session will be filled with required infomration
- * upon completion
- */
- void assignSession(AuthSessionPtr session)
- {
- m_session = session;
- }
-
- /// get the assigned session for filling with information.
- AuthSessionPtr getAssignedSession()
- {
- return m_session;
- }
-
- /**
- * Class describing a Account error response.
- */
- struct Error
- {
- QString m_errorMessageShort;
- QString m_errorMessageVerbose;
- QString m_cause;
- };
-
- enum AbortedBy
- {
- BY_NOTHING,
- BY_USER,
- BY_TIMEOUT
- } m_aborted = BY_NOTHING;
-
- /**
- * Enum for describing the state of the current task.
- * Used by the getStateMessage function to determine what the status message should be.
- */
- enum State
- {
- STATE_CREATED,
- STATE_WORKING,
- STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
- STATE_FAILED_HARD, //!< hard failure. auth is invalid
- STATE_FAILED_GONE, //!< hard failure. auth is invalid, and the account no longer exists
- STATE_SUCCEEDED
- } m_accountState = STATE_CREATED;
+ AccountTaskState m_taskState = AccountTaskState::STATE_CREATED;
- State accountState() {
- return m_accountState;
+ AccountTaskState taskState() {
+ return m_taskState;
}
signals:
@@ -98,11 +68,9 @@ protected:
virtual QString getStateMessage() const;
protected slots:
- void changeState(State newState, QString reason=QString());
+ // NOTE: true -> non-terminal state, false -> terminal state
+ bool changeState(AccountTaskState newState, QString reason = QString());
protected:
- // FIXME: segfault disaster waiting to happen
AccountData *m_data = nullptr;
- std::shared_ptr<Error> m_error;
- AuthSessionPtr m_session;
};
diff --git a/launcher/minecraft/auth/flows/AuthRequest.cpp b/launcher/minecraft/auth/AuthRequest.cpp
index 77558fd3..459d2354 100644
--- a/launcher/minecraft/auth/flows/AuthRequest.cpp
+++ b/launcher/minecraft/auth/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()));
@@ -44,6 +44,7 @@ void AuthRequest::onRequestFinished() {
if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
return;
}
+ httpStatus_ = 200;
finish();
}
@@ -55,10 +56,11 @@ void AuthRequest::onRequestError(QNetworkReply::NetworkError error) {
if (reply_ != qobject_cast<QNetworkReply *>(sender())) {
return;
}
- qWarning() << "AuthRequest::onRequestError: Error string: " << reply_->errorString();
- int httpStatus = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- qWarning() << "AuthRequest::onRequestError: HTTP status" << httpStatus << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
+ errorString_ = reply_->errorString();
+ httpStatus_ = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
error_ = error;
+ qWarning() << "AuthRequest::onRequestError: Error string: " << errorString_;
+ qWarning() << "AuthRequest::onRequestError: HTTP status" << httpStatus_ << reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
// QTimer::singleShot(10, this, SLOT(finish()));
}
@@ -103,6 +105,8 @@ void AuthRequest::setup(const QNetworkRequest &req, QNetworkAccessManager::Opera
status_ = Requesting;
error_ = QNetworkReply::NoError;
+ errorString_.clear();
+ httpStatus_ = 0;
}
void AuthRequest::finish() {
diff --git a/launcher/minecraft/auth/flows/AuthRequest.h b/launcher/minecraft/auth/AuthRequest.h
index 6a45a0bd..89f7a123 100644
--- a/launcher/minecraft/auth/flows/AuthRequest.h
+++ b/launcher/minecraft/auth/AuthRequest.h
@@ -5,7 +5,6 @@
#include <QNetworkAccessManager>
#include <QUrl>
#include <QByteArray>
-#include <QHttpMultiPart>
#include "katabasis/Reply.h"
@@ -47,6 +46,11 @@ protected slots:
/// Handle upload progress.
void onUploadProgress(qint64 uploaded, qint64 total);
+public:
+ QNetworkReply::NetworkError error_;
+ int httpStatus_ = 0;
+ QString errorString_;
+
protected:
void setup(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &verb = QByteArray());
@@ -61,5 +65,6 @@ protected:
QNetworkAccessManager::Operation operation_;
QUrl url_;
Katabasis::ReplyList timedReplies_;
- QNetworkReply::NetworkError error_;
+
+ QTimer *timer_;
};
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/AuthStep.cpp b/launcher/minecraft/auth/AuthStep.cpp
new file mode 100644
index 00000000..ffa2581b
--- /dev/null
+++ b/launcher/minecraft/auth/AuthStep.cpp
@@ -0,0 +1,7 @@
+#include "AuthStep.h"
+
+AuthStep::AuthStep(AccountData *data) : QObject(nullptr), m_data(data) {
+}
+
+AuthStep::~AuthStep() noexcept = default;
+
diff --git a/launcher/minecraft/auth/AuthStep.h b/launcher/minecraft/auth/AuthStep.h
new file mode 100644
index 00000000..2a8dc2ca
--- /dev/null
+++ b/launcher/minecraft/auth/AuthStep.h
@@ -0,0 +1,33 @@
+#pragma once
+#include <QObject>
+#include <QList>
+#include <QNetworkReply>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AccountData.h"
+#include "AccountTask.h"
+
+class AuthStep : public QObject {
+ Q_OBJECT
+
+public:
+ using Ptr = shared_qobject_ptr<AuthStep>;
+
+public:
+ explicit AuthStep(AccountData *data);
+ virtual ~AuthStep() noexcept;
+
+ virtual QString describe() = 0;
+
+public slots:
+ virtual void perform() = 0;
+ virtual void rehydrate() = 0;
+
+signals:
+ void finished(AccountTaskState resultingState, QString message);
+ void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn);
+ void hideVerificationUriAndCode();
+
+protected:
+ AccountData *m_data;
+};
diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp
index 2d76f9ac..ed9e945e 100644
--- a/launcher/minecraft/auth/MinecraftAccount.cpp
+++ b/launcher/minecraft/auth/MinecraftAccount.cpp
@@ -16,7 +16,6 @@
*/
#include "MinecraftAccount.h"
-#include "flows/AuthContext.h"
#include <QUuid>
#include <QJsonObject>
@@ -28,11 +27,14 @@
#include <QDebug>
#include <QPainter>
-#include <minecraft/auth/flows/MSASilent.h>
-#include <minecraft/auth/flows/MSAInteractive.h>
-#include <minecraft/auth/flows/MojangRefresh.h>
-#include <minecraft/auth/flows/MojangLogin.h>
+#include "flows/MSA.h"
+#include "flows/Mojang.h"
+
+MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) {
+ data.internalId = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
+}
+
MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json) {
MinecraftAccountPtr account(new MinecraftAccount());
@@ -52,7 +54,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("[{}-]"));
@@ -72,23 +74,8 @@ QJsonObject MinecraftAccount::saveToJson() const
return data.saveState();
}
-AccountStatus MinecraftAccount::accountStatus() const {
- if(data.type == AccountType::Mojang) {
- if (data.accessToken().isEmpty()) {
- return NotVerified;
- }
- else {
- return Verified;
- }
- }
- // MSA
- // FIXME: this is extremely crude and probably wrong
- if(data.msaToken.token.isEmpty()) {
- return NotVerified;
- }
- else {
- return Verified;
- }
+AccountState MinecraftAccount::accountState() const {
+ return data.accountState;
}
QPixmap MinecraftAccount::getFace() const {
@@ -104,190 +91,146 @@ QPixmap MinecraftAccount::getFace() const {
}
-std::shared_ptr<AccountTask> MinecraftAccount::login(AuthSessionPtr session, QString password)
-{
+shared_qobject_ptr<AccountTask> MinecraftAccount::login(QString password) {
Q_ASSERT(m_currentTask.get() == nullptr);
- // take care of the true offline status
- if (accountStatus() == NotVerified && password.isEmpty())
- {
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- fillSession(session);
- }
- return nullptr;
- }
-
- if(accountStatus() == Verified && !session->wants_online)
- {
- session->status = AuthSession::PlayableOffline;
- session->auth_server_online = false;
- fillSession(session);
- return nullptr;
- }
- else
- {
- if (password.isEmpty())
- {
- m_currentTask.reset(new MojangRefresh(&data));
- }
- else
- {
- m_currentTask.reset(new MojangLogin(&data, password));
- }
- m_currentTask->assignSession(session);
-
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
- }
+ m_currentTask.reset(new MojangLogin(&data, password));
+ 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() {
Q_ASSERT(m_currentTask.get() == nullptr);
- if(accountStatus() == Verified && !session->wants_online)
- {
- session->status = AuthSession::PlayableOffline;
- session->auth_server_online = false;
- fillSession(session);
- return nullptr;
- }
- else
- {
- m_currentTask.reset(new MSAInteractive(&data));
- m_currentTask->assignSession(session);
-
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
- }
+ m_currentTask.reset(new MSAInteractive(&data));
+ 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) {
- Q_ASSERT(m_currentTask.get() == nullptr);
-
- // take care of the true offline status
- if (accountStatus() == NotVerified)
- {
- if (session)
- {
- if(data.type == AccountType::MSA) {
- session->status = AuthSession::RequiresOAuth;
- }
- else {
- session->status = AuthSession::RequiresPassword;
- }
- fillSession(session);
- }
- return nullptr;
+shared_qobject_ptr<AccountTask> MinecraftAccount::refresh() {
+ if(m_currentTask) {
+ return m_currentTask;
}
- if(accountStatus() == Verified && !session->wants_online)
- {
- session->status = AuthSession::PlayableOffline;
- session->auth_server_online = false;
- fillSession(session);
- return nullptr;
+ if(data.type == AccountType::MSA) {
+ m_currentTask.reset(new MSASilent(&data));
}
- else
- {
- if(data.type == AccountType::MSA) {
- m_currentTask.reset(new MSASilent(&data));
- }
- else {
- m_currentTask.reset(new MojangRefresh(&data));
- }
- m_currentTask->assignSession(session);
-
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
+ else {
+ m_currentTask.reset(new MojangRefresh(&data));
}
+
+ connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
+ connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
+ emit activityChanged(true);
+ return m_currentTask;
+}
+
+shared_qobject_ptr<AccountTask> MinecraftAccount::currentTask() {
return m_currentTask;
}
void MinecraftAccount::authSucceeded()
{
- auto session = m_currentTask->getAssignedSession();
- if (session)
- {
- session->status =
- session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
- fillSession(session);
- session->auth_server_online = true;
- }
m_currentTask.reset();
emit changed();
+ emit activityChanged(false);
}
void MinecraftAccount::authFailed(QString reason)
{
- auto session = m_currentTask->getAssignedSession();
- // This is emitted when the yggdrasil tasks time out or are cancelled.
- // -> we treat the error as no-op
- switch (m_currentTask->accountState()) {
- case AccountTask::STATE_FAILED_SOFT: {
- if (session)
- {
- if(accountStatus() == Verified) {
- session->status = AuthSession::PlayableOffline;
- }
- else {
- if(data.type == AccountType::MSA) {
- session->status = AuthSession::RequiresOAuth;
- }
- else {
- session->status = AuthSession::RequiresPassword;
- }
- }
- session->auth_server_online = false;
- fillSession(session);
- }
+ switch (m_currentTask->taskState()) {
+ case AccountTaskState::STATE_OFFLINE:
+ case AccountTaskState::STATE_FAILED_SOFT: {
+ // NOTE: this doesn't do much. There was an error of some sort.
}
break;
- case AccountTask::STATE_FAILED_HARD: {
- // FIXME: MSA data clearing
- data.yggdrasilToken.token = QString();
- data.yggdrasilToken.validity = Katabasis::Validity::None;
- data.validity_ = Katabasis::Validity::None;
- emit changed();
- if (session)
- {
- if(data.type == AccountType::MSA) {
- session->status = AuthSession::RequiresOAuth;
- }
- else {
- session->status = AuthSession::RequiresPassword;
- }
- session->auth_server_online = true;
- fillSession(session);
+ case AccountTaskState::STATE_FAILED_HARD: {
+ if(isMSA()) {
+ data.msaToken.token = QString();
+ data.msaToken.refresh_token = QString();
+ data.msaToken.validity = Katabasis::Validity::None;
+ data.validity_ = Katabasis::Validity::None;
}
+ else {
+ data.yggdrasilToken.token = QString();
+ data.yggdrasilToken.validity = Katabasis::Validity::None;
+ data.validity_ = Katabasis::Validity::None;
+ }
+ emit changed();
}
break;
- case AccountTask::STATE_FAILED_GONE: {
+ case AccountTaskState::STATE_FAILED_GONE: {
data.validity_ = Katabasis::Validity::None;
emit changed();
- if (session)
- {
- session->status = AuthSession::GoneOrMigrated;
- session->auth_server_online = true;
- fillSession(session);
- }
}
break;
- case AccountTask::STATE_CREATED:
- case AccountTask::STATE_WORKING:
- case AccountTask::STATE_SUCCEEDED: {
+ case AccountTaskState::STATE_CREATED:
+ case AccountTaskState::STATE_WORKING:
+ case AccountTaskState::STATE_SUCCEEDED: {
// Not reachable here, as they are not failures.
}
}
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)
{
+ if(ownsMinecraft() && !hasProfile()) {
+ session->status = AuthSession::RequiresProfileSetup;
+ }
+ else {
+ if(session->wants_online) {
+ session->status = AuthSession::PlayableOnline;
+ }
+ else {
+ session->status = AuthSession::PlayableOffline;
+ }
+ }
+
// the user name. you have to have an user name
// FIXME: not with MSA
session->username = data.userName();
@@ -309,7 +252,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..4ac0a3e5 100644
--- a/launcher/minecraft/auth/MinecraftAccount.h
+++ b/launcher/minecraft/auth/MinecraftAccount.h
@@ -24,15 +24,17 @@
#include <QPixmap>
#include <memory>
+
#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)
/**
@@ -49,12 +51,6 @@ struct AccountProfile
bool legacy;
};
-enum AccountStatus
-{
- NotVerified,
- Verified
-};
-
/**
* Object that stores information about a certain Mojang account.
*
@@ -63,8 +59,7 @@ enum AccountStatus
*/
class MinecraftAccount :
public QObject,
- public Usable,
- public std::enable_shared_from_this<MinecraftAccount>
+ public Usable
{
Q_OBJECT
public: /* construction */
@@ -72,7 +67,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 +85,19 @@ 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(QString password);
+
+ shared_qobject_ptr<AccountTask> loginMSA();
- std::shared_ptr<AccountTask> loginMSA(AuthSessionPtr session);
+ shared_qobject_ptr<AccountTask> refresh();
- std::shared_ptr<AccountTask> refresh(AuthSessionPtr session);
+ shared_qobject_ptr<AccountTask> currentTask();
public: /* queries */
+ QString internalId() const {
+ return data.internalId;
+ }
+
QString accountDisplayString() const {
return data.accountDisplayString();
}
@@ -117,6 +118,8 @@ public: /* queries */
return data.profileName();
}
+ bool isActive() const;
+
bool canMigrate() const {
return data.canMigrateToMSA;
}
@@ -125,6 +128,14 @@ public: /* queries */
return data.type == AccountType::MSA;
}
+ bool ownsMinecraft() const {
+ return data.minecraftEntitlement.ownsMinecraft;
+ }
+
+ bool hasProfile() const {
+ return data.profileId().size() != 0;
+ }
+
QString typeString() const {
switch(data.type) {
case AccountType::Mojang: {
@@ -146,26 +157,36 @@ public: /* queries */
QPixmap getFace() const;
- //! Returns whether the account is NotVerified, Verified or Online
- AccountStatus accountStatus() const;
+ //! Returns the current state of the account
+ AccountState accountState() const;
AccountData * accountData() {
return &data;
}
+ bool shouldRefresh() const;
+
+ void fillSession(AuthSessionPtr session);
+
+ QString lastError() const {
+ return data.lastError();
+ }
+
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 */
AccountData data;
// current task we are executing here
- std::shared_ptr<AccountTask> m_currentTask;
+ shared_qobject_ptr<AccountTask> m_currentTask;
protected: /* methods */
@@ -176,7 +197,4 @@ private
slots:
void authSucceeded();
void authFailed(QString reason);
-
-private:
- void fillSession(AuthSessionPtr session);
};
diff --git a/launcher/minecraft/auth/Parsers.cpp b/launcher/minecraft/auth/Parsers.cpp
new file mode 100644
index 00000000..4cab78ef
--- /dev/null
+++ b/launcher/minecraft/auth/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, QString 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/Parsers.h b/launcher/minecraft/auth/Parsers.h
new file mode 100644
index 00000000..dac7f69b
--- /dev/null
+++ b/launcher/minecraft/auth/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, QString 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/Yggdrasil.cpp
index 20ca63d0..7ac842a6 100644
--- a/launcher/minecraft/auth/flows/Yggdrasil.cpp
+++ b/launcher/minecraft/auth/Yggdrasil.cpp
@@ -14,7 +14,7 @@
*/
#include "Yggdrasil.h"
-#include "../AccountData.h"
+#include "AccountData.h"
#include <QObject>
#include <QString>
@@ -23,24 +23,22 @@
#include <QNetworkReply>
#include <QByteArray>
-#include <Env.h>
-
-#include <BuildConfig.h>
-
#include <QDebug>
+#include "Application.h"
+
Yggdrasil::Yggdrasil(AccountData *data, QObject *parent)
: AccountTask(data, parent)
{
- changeState(STATE_CREATED);
+ changeState(AccountTaskState::STATE_CREATED);
}
void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) {
- changeState(STATE_WORKING);
+ changeState(AccountTaskState::STATE_WORKING);
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,65 +183,63 @@ 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."));
+ changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
return;
}
if(m_data->clientToken().isEmpty()) {
m_data->setClientToken(clientToken);
}
else if(clientToken != m_data->clientToken()) {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
+ changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
return;
}
// Now, we set the access token.
qDebug() << "Getting 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."));
+ changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
return;
}
// 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.
qDebug() << "Finished reading authentication response.";
- changeState(STATE_SUCCEEDED);
+ changeState(AccountTaskState::STATE_SUCCEEDED);
}
-void Yggdrasil::processReply()
-{
- changeState(STATE_WORKING);
+void Yggdrasil::processReply() {
+ changeState(AccountTaskState::STATE_WORKING);
switch (m_netReply->error())
{
case QNetworkReply::NoError:
break;
case QNetworkReply::TimeoutError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out."));
+ changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation timed out."));
return;
case QNetworkReply::OperationCanceledError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
+ changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
return;
case QNetworkReply::SslHandshakeFailedError:
changeState(
- STATE_FAILED_SOFT,
+ AccountTaskState::STATE_FAILED_SOFT,
tr(
"<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
"<ul>"
"<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.
@@ -258,13 +248,13 @@ void Yggdrasil::processReply()
break;
case QNetworkReply::ContentGoneError: {
changeState(
- STATE_FAILED_GONE,
+ AccountTaskState::STATE_FAILED_GONE,
tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.")
);
}
default:
changeState(
- STATE_FAILED_SOFT,
+ AccountTaskState::STATE_FAILED_SOFT,
tr("Authentication operation failed due to a network error: %1 (%2)").arg(m_netReply->errorString()).arg(m_netReply->error())
);
return;
@@ -278,21 +268,18 @@ 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,
+ AccountTaskState::STATE_FAILED_SOFT,
tr("Failed to parse authentication server response JSON response: %1 at offset %2.").arg(jsonError.errorString()).arg(jsonError.offset)
);
qCritical() << replyData;
@@ -304,34 +291,30 @@ 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.";
changeState(
- STATE_FAILED_SOFT,
+ AccountTaskState::STATE_FAILED_SOFT,
tr("An unknown error occurred when trying to communicate with the authentication server: %1").arg(m_netReply->errorString())
);
}
}
-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(""),
@@ -339,11 +322,10 @@ void Yggdrasil::processError(QJsonObject responseData)
causeVal.toString("")
}
);
- changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
+ changeState(AccountTaskState::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."));
+ changeState(AccountTaskState::STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
}
}
diff --git a/launcher/minecraft/auth/flows/Yggdrasil.h b/launcher/minecraft/auth/Yggdrasil.h
index e709cb9f..4f52a04c 100644
--- a/launcher/minecraft/auth/flows/Yggdrasil.h
+++ b/launcher/minecraft/auth/Yggdrasil.h
@@ -15,15 +15,16 @@
#pragma once
-#include "../AccountTask.h"
+#include "AccountTask.h"
#include <QString>
#include <QJsonObject>
#include <QTimer>
#include <qsslerror.h>
-#include "../MinecraftAccount.h"
+#include "MinecraftAccount.h"
+class QNetworkAccessManager;
class QNetworkReply;
/**
@@ -33,11 +34,30 @@ class Yggdrasil : public AccountTask
{
Q_OBJECT
public:
- explicit Yggdrasil(AccountData * data, QObject *parent = 0);
- virtual ~Yggdrasil() {};
+ explicit Yggdrasil(
+ AccountData *data,
+ QObject *parent = 0
+ );
+ virtual ~Yggdrasil() = default;
void refresh();
void login(QString password);
+
+ struct Error
+ {
+ QString m_errorMessageShort;
+ QString m_errorMessageVerbose;
+ QString m_cause;
+ };
+ std::shared_ptr<Error> m_error;
+
+ enum AbortedBy
+ {
+ BY_NOTHING,
+ BY_USER,
+ BY_TIMEOUT
+ } m_aborted = BY_NOTHING;
+
protected:
void executeTask() override;
diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp
deleted file mode 100644
index 9fb3ec48..00000000
--- a/launcher/minecraft/auth/flows/AuthContext.cpp
+++ /dev/null
@@ -1,911 +0,0 @@
-#include <QNetworkAccessManager>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QDesktopServices>
-#include <QMetaEnum>
-#include <QDebug>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-
-#include <QUrlQuery>
-
-#include <QPixmap>
-#include <QPainter>
-
-#include "AuthContext.h"
-#include "katabasis/Globals.h"
-#include "AuthRequest.h"
-
-#include "Secrets.h"
-
-#include "Env.h"
-
-using OAuth2 = Katabasis::OAuth2;
-using Activity = Katabasis::Activity;
-
-AuthContext::AuthContext(AccountData * data, QObject *parent) :
- AccountTask(data, parent)
-{
-}
-
-void AuthContext::beginActivity(Activity activity) {
- if(isBusy()) {
- throw 0;
- }
- m_activity = activity;
- changeState(STATE_WORKING, "Initializing");
- emit activityChanged(m_activity);
-}
-
-void AuthContext::finishActivity() {
- if(!isBusy()) {
- throw 0;
- }
- m_activity = Katabasis::Activity::Idle;
- setStage(AuthStage::Complete);
- m_data->validity_ = m_data->minecraftProfile.validity;
- emit activityChanged(m_activity);
-}
-
-void AuthContext::initMSA() {
- if(m_oauth2) {
- return;
- }
-
- auto clientId = Secrets::getMSAClientID('-');
- if(clientId.isEmpty()) {
- return;
- }
-
- Katabasis::OAuth2::Options opts;
- opts.scope = "XboxLive.signin offline_access";
- opts.clientIdentifier = clientId;
- 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);
-
- 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);
-}
-
-void AuthContext::initMojang() {
- if(m_yggdrasil) {
- return;
- }
- m_yggdrasil = new Yggdrasil(m_data, this);
-
- connect(m_yggdrasil, &Task::failed, this, &AuthContext::onMojangFailed);
- connect(m_yggdrasil, &Task::succeeded, this, &AuthContext::onMojangSucceeded);
-}
-
-void AuthContext::onMojangSucceeded() {
- doMinecraftProfile();
-}
-
-
-void AuthContext::onMojangFailed() {
- finishActivity();
- m_error = m_yggdrasil->m_error;
- m_aborted = m_yggdrasil->m_aborted;
- 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);
- }
- }
-#endif
- doUserAuth();
-}
-
-void AuthContext::onOAuthActivityChanged(Katabasis::Activity activity) {
- // respond to activity change here
-}
-
-void AuthContext::doUserAuth() {
- setStage(AuthStage::UserAuth);
- changeState(STATE_WORKING, tr("Starting user authentication"));
-
- QString xbox_auth_template = R"XXX(
-{
- "Properties": {
- "AuthMethod": "RPS",
- "SiteName": "user.auth.xboxlive.com",
- "RpsTicket": "d=%1"
- },
- "RelyingParty": "http://auth.xboxlive.com",
- "TokenType": "JWT"
-}
-)XXX";
- auto xbox_auth_data = xbox_auth_template.arg(m_data->msaToken.token);
-
- QNetworkRequest request = QNetworkRequest(QUrl("https://user.auth.xboxlive.com/user/authenticate"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- request.setRawHeader("Accept", "application/json");
- auto *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onUserAuthDone);
- requestor->post(request, xbox_auth_data.toUtf8());
- 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,
- QList<QNetworkReply::RawHeaderPair> headers
-) {
- if (error != QNetworkReply::NoError) {
- qWarning() << "Reply error:" << error;
- finishActivity();
- changeState(STATE_FAILED_HARD, tr("XBox user authentication failed."));
- return;
- }
-
- Katabasis::Token temp;
- if(!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."));
- return;
- }
- m_data->userToken = temp;
-
- setStage(AuthStage::XboxAuth);
- changeState(STATE_WORKING, tr("Starting XBox authentication"));
-
- doSTSAuthMinecraft();
- doSTSAuthGeneric();
-}
-/*
- url = "https://xsts.auth.xboxlive.com/xsts/authorize"
- headers = {"x-xbl-contract-version": "1"}
- data = {
- "RelyingParty": relying_party,
- "TokenType": "JWT",
- "Properties": {
- "UserTokens": [self.user_token.token],
- "SandboxId": "RETAIL",
- },
- }
-*/
-void AuthContext::doSTSAuthMinecraft() {
- QString xbox_auth_template = R"XXX(
-{
- "Properties": {
- "SandboxId": "RETAIL",
- "UserTokens": [
- "%1"
- ]
- },
- "RelyingParty": "rp://api.minecraftservices.com/",
- "TokenType": "JWT"
-}
-)XXX";
- auto xbox_auth_data = xbox_auth_template.arg(m_data->userToken.token);
-
- QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- request.setRawHeader("Accept", "application/json");
- AuthRequest *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthMinecraftDone);
- requestor->post(request, xbox_auth_data.toUtf8());
- qDebug() << "Getting Minecraft services STS token...";
-}
-
-void AuthContext::processSTSError(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers) {
- if(error == QNetworkReply::AuthenticationRequiredError) {
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if(jsonError.error) {
- qWarning() << "Cannot parse error XSTS response as JSON: " << jsonError.errorString();
- return;
- }
-
- int64_t errorCode = -1;
- auto obj = doc.object();
- if(!getNumber(obj.value("XErr"), errorCode)) {
- qWarning() << "XErr is not a number";
- return;
- }
- stsErrors.insert(errorCode);
- stsFailed = true;
- }
-}
-
-
-void AuthContext::onSTSAuthMinecraftDone(
- QNetworkReply::NetworkError error,
- QByteArray replyData,
- QList<QNetworkReply::RawHeaderPair> headers
-) {
-#ifndef NDEBUG
- qDebug() << replyData;
-#endif
- if (error != QNetworkReply::NoError) {
- qWarning() << "Reply error:" << error;
- processSTSError(error, replyData, headers);
- failResult(m_mcAuthSucceeded);
- return;
- }
-
- Katabasis::Token temp;
- if(!parseXTokenResponse(replyData, temp, "STSAuthMinecraft")) {
- qWarning() << "Could not parse authorization response for access to mojang services...";
- failResult(m_mcAuthSucceeded);
- return;
- }
-
- if(temp.extra["uhs"] != m_data->userToken.extra["uhs"]) {
- qWarning() << "Server has changed user hash in the reply... something is wrong. ABORTING";
- failResult(m_mcAuthSucceeded);
- return;
- }
- m_data->mojangservicesToken = temp;
-
- doMinecraftAuth();
-}
-
-void AuthContext::doMinecraftAuth() {
- QString mc_auth_template = R"XXX(
-{
- "identityToken": "XBL3.0 x=%1;%2"
-}
-)XXX";
- auto data = mc_auth_template.arg(m_data->mojangservicesToken.extra["uhs"].toString(), m_data->mojangservicesToken.token);
-
- QNetworkRequest request = QNetworkRequest(QUrl("https://api.minecraftservices.com/authentication/login_with_xbox"));
- 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());
- 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
-) {
- if (error != QNetworkReply::NoError) {
- qWarning() << "Reply error:" << error;
-#ifndef NDEBUG
- qDebug() << replyData;
-#endif
- failResult(m_mcAuthSucceeded);
- return;
- }
-
- if(!parseMojangResponse(replyData, m_data->yggdrasilToken)) {
- qWarning() << "Could not parse login_with_xbox response...";
-#ifndef NDEBUG
- qDebug() << replyData;
-#endif
- failResult(m_mcAuthSucceeded);
- return;
- }
-
- succeedResult(m_mcAuthSucceeded);
-}
-
-void AuthContext::doSTSAuthGeneric() {
- QString xbox_auth_template = R"XXX(
-{
- "Properties": {
- "SandboxId": "RETAIL",
- "UserTokens": [
- "%1"
- ]
- },
- "RelyingParty": "http://xboxlive.com",
- "TokenType": "JWT"
-}
-)XXX";
- auto xbox_auth_data = xbox_auth_template.arg(m_data->userToken.token);
-
- QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- request.setRawHeader("Accept", "application/json");
- AuthRequest *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onSTSAuthGenericDone);
- requestor->post(request, xbox_auth_data.toUtf8());
- qDebug() << "Getting generic STS token...";
-}
-
-void AuthContext::onSTSAuthGenericDone(
- QNetworkReply::NetworkError error,
- QByteArray replyData,
- QList<QNetworkReply::RawHeaderPair> headers
-) {
-#ifndef NDEBUG
- qDebug() << replyData;
-#endif
- if (error != QNetworkReply::NoError) {
- qWarning() << "Reply error:" << error;
- processSTSError(error, replyData, headers);
- failResult(m_xboxProfileSucceeded);
- return;
- }
-
- Katabasis::Token temp;
- if(!parseXTokenResponse(replyData, temp, "STSAuthGeneric")) {
- qWarning() << "Could not parse authorization response for access to xbox API...";
- failResult(m_xboxProfileSucceeded);
- return;
- }
-
- if(temp.extra["uhs"] != m_data->userToken.extra["uhs"]) {
- qWarning() << "Server has changed user hash in the reply... something is wrong. ABORTING";
- failResult(m_xboxProfileSucceeded);
- return;
- }
- m_data->xboxApiToken = temp;
-
- doXBoxProfile();
-}
-
-void AuthContext::doXBoxProfile() {
- auto url = QUrl("https://profile.xboxlive.com/users/me/profile/settings");
- QUrlQuery q;
- q.addQueryItem(
- "settings",
- "GameDisplayName,AppDisplayName,AppDisplayPicRaw,GameDisplayPicRaw,"
- "PublicGamerpic,ShowUserAsAvatar,Gamerscore,Gamertag,ModernGamertag,ModernGamertagSuffix,"
- "UniqueModernGamertag,AccountTier,TenureLevel,XboxOneRep,"
- "PreferredColor,Location,Bio,Watermarks,"
- "RealName,RealNameOverride,IsQuarantined"
- );
- url.setQuery(q);
-
- QNetworkRequest request = QNetworkRequest(url);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- request.setRawHeader("Accept", "application/json");
- request.setRawHeader("x-xbl-contract-version", "3");
- request.setRawHeader("Authorization", QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8());
- AuthRequest *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onXBoxProfileDone);
- requestor->get(request);
- qDebug() << "Getting Xbox profile...";
-}
-
-void AuthContext::onXBoxProfileDone(
- QNetworkReply::NetworkError error,
- QByteArray replyData,
- QList<QNetworkReply::RawHeaderPair> headers
-) {
- if (error != QNetworkReply::NoError) {
- qWarning() << "Reply error:" << error;
-#ifndef NDEBUG
- qDebug() << replyData;
-#endif
- failResult(m_xboxProfileSucceeded);
- return;
- }
-
-#ifndef NDEBUG
- qDebug() << "XBox profile: " << replyData;
-#endif
-
- succeedResult(m_xboxProfileSucceeded);
-}
-
-void AuthContext::succeedResult(bool& flag) {
- m_requestsDone ++;
- flag = true;
- checkResult();
-}
-
-void AuthContext::failResult(bool& flag) {
- m_requestsDone ++;
- flag = false;
- checkResult();
-}
-
-void AuthContext::checkResult() {
- qDebug() << "AuthContext::checkResult called";
- if(m_requestsDone != 2) {
- qDebug() << "Number of ready results:" << m_requestsDone;
- return;
- }
- if(m_mcAuthSucceeded && m_xboxProfileSucceeded) {
- doMinecraftProfile();
- }
- else {
- finishActivity();
- if(stsFailed) {
- if(stsErrors.contains(2148916233)) {
- changeState(
- STATE_FAILED_HARD,
- tr("This Microsoft account does not have an XBox Live profile. Buy the game on %1 first.")
- .arg("<a href=\"https://www.minecraft.net/en-us/store/minecraft-java-edition\">minecraft.net</a>")
- );
- }
- else if (stsErrors.contains(2148916235)){
- // NOTE: this is the Grulovia error
- changeState(
- STATE_FAILED_HARD,
- tr("XBox Live is not available in your country. You've been blocked.")
- );
- }
- else if (stsErrors.contains(2148916238)){
- changeState(
- STATE_FAILED_HARD,
- tr("This Microsoft account is underaged and is not linked to a family.\n\nPlease set up your account according to %1.")
- .arg("<a href=\"https://help.minecraft.net/hc/en-us/articles/4403181904525\">help.minecraft.net</a>")
- );
- }
- else {
- QStringList errorList;
- for(auto & error: stsErrors) {
- errorList.append(QString::number(error));
- }
- changeState(
- STATE_FAILED_HARD,
- tr("XSTS authentication ended with unrecognized error(s):\n\n%1").arg(errorList.join("\n"))
- );
- }
- }
- else {
- changeState(STATE_FAILED_HARD, tr("XBox and/or Mojang authentication steps did not succeed"));
- }
- }
-}
-
-namespace {
-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;
-}
-}
-
-void AuthContext::doMinecraftProfile() {
- setStage(AuthStage::MinecraftProfile);
- changeState(STATE_WORKING, tr("Starting minecraft profile acquisition"));
-
- auto url = QUrl("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(m_data->yggdrasilToken.token).toUtf8());
-
- AuthRequest *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftProfileDone);
- requestor->get(request);
-}
-
-void AuthContext::onMinecraftProfileDone(
- QNetworkReply::NetworkError error,
- QByteArray data,
- QList<QNetworkReply::RawHeaderPair> headers
-) {
-#ifndef NDEBUG
- qDebug() << data;
-#endif
- if (error == QNetworkReply::ContentNotFoundError) {
- 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."));
- return;
- }
- if (error != QNetworkReply::NoError) {
- finishActivity();
- changeState(STATE_FAILED_HARD, tr("Minecraft Java profile acquisition failed."));
- return;
- }
- if(!parseMinecraftProfile(data, m_data->minecraftProfile)) {
- m_data->minecraftProfile = MinecraftProfile();
- finishActivity();
- changeState(STATE_FAILED_HARD, tr("Minecraft Java profile response could not be parsed"));
- return;
- }
-
- if(m_data->type == AccountType::Mojang) {
- doMigrationEligibilityCheck();
- }
- else {
- doGetSkin();
- }
-}
-
-void AuthContext::doMigrationEligibilityCheck() {
- setStage(AuthStage::MigrationEligibility);
- changeState(STATE_WORKING, tr("Starting check for migration eligibility"));
-
- auto url = QUrl("https://api.minecraftservices.com/rollout/v1/msamigration");
- QNetworkRequest request = QNetworkRequest(url);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "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::onMigrationEligibilityCheckDone);
- 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);
- }
- doGetSkin();
-}
-
-void AuthContext::doGetSkin() {
- setStage(AuthStage::Skin);
- changeState(STATE_WORKING, tr("Fetching player skin"));
-
- auto url = QUrl(m_data->minecraftProfile.skin.url);
- QNetworkRequest request = QNetworkRequest(url);
- AuthRequest *requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &AuthContext::onSkinDone);
- requestor->get(request);
-}
-
-void AuthContext::onSkinDone(
- QNetworkReply::NetworkError error,
- QByteArray data,
- QList<QNetworkReply::RawHeaderPair>
-) {
- if (error == QNetworkReply::NoError) {
- m_data->minecraftProfile.skin.data = data;
- }
- m_data->validity_ = Katabasis::Validity::Certain;
- finishActivity();
- changeState(STATE_SUCCEEDED, tr("Finished all authentication steps"));
-}
-
-void AuthContext::setStage(AuthContext::AuthStage stage) {
- m_stage = stage;
- emit progress((int)m_stage, (int)AuthStage::Complete);
-}
-
-
-QString AuthContext::getStateMessage() const {
- switch (m_accountState)
- {
- case STATE_WORKING:
- switch(m_stage) {
- case AuthStage::Initial: {
- QString loginMessage = tr("Logging in as %1 user");
- if(m_data->type == AccountType::MSA) {
- return loginMessage.arg("Microsoft");
- }
- else {
- return loginMessage.arg("Mojang");
- }
- }
- case AuthStage::UserAuth:
- return tr("Logging in as XBox user");
- case AuthStage::XboxAuth:
- return tr("Logging in with XBox and Mojang services");
- case AuthStage::MinecraftProfile:
- return tr("Getting Minecraft profile");
- case AuthStage::MigrationEligibility:
- return tr("Checking for migration eligibility");
- case AuthStage::Skin:
- return tr("Getting Minecraft skin");
- case AuthStage::Complete:
- return tr("Finished");
- default:
- break;
- }
- default:
- return AccountTask::getStateMessage();
- }
-}
diff --git a/launcher/minecraft/auth/flows/AuthContext.h b/launcher/minecraft/auth/flows/AuthContext.h
deleted file mode 100644
index dc7552ac..00000000
--- a/launcher/minecraft/auth/flows/AuthContext.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#pragma once
-
-#include <QObject>
-#include <QList>
-#include <QVector>
-#include <QSet>
-#include <QNetworkReply>
-#include <QImage>
-
-#include <katabasis/OAuth2.h>
-#include "Yggdrasil.h"
-#include "../AccountData.h"
-#include "../AccountTask.h"
-
-class AuthContext : public AccountTask
-{
- Q_OBJECT
-
-public:
- explicit AuthContext(AccountData * data, QObject *parent = 0);
-
- bool isBusy() {
- return m_activity != Katabasis::Activity::Idle;
- };
- Katabasis::Validity validity() {
- return m_data->validity_;
- };
-
- //bool signOut();
-
- QString getStateMessage() const override;
-
-signals:
- void activityChanged(Katabasis::Activity activity);
-
-private slots:
-// OAuth-specific callbacks
- void onOAuthLinkingSucceeded();
- void onOAuthLinkingFailed();
-
- void onOAuthActivityChanged(Katabasis::Activity activity);
-
-// Yggdrasil specific callbacks
- void onMojangSucceeded();
- void onMojangFailed();
-
-protected:
- void initMSA();
- void initMojang();
-
- void doUserAuth();
- Q_SLOT void onUserAuthDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void processSTSError(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void doSTSAuthMinecraft();
- Q_SLOT void onSTSAuthMinecraftDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
- void doMinecraftAuth();
- Q_SLOT void onMinecraftAuthDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void doSTSAuthGeneric();
- Q_SLOT void onSTSAuthGenericDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
- void doXBoxProfile();
- Q_SLOT void onXBoxProfileDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void doMinecraftProfile();
- Q_SLOT void onMinecraftProfileDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void doMigrationEligibilityCheck();
- Q_SLOT void onMigrationEligibilityCheckDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void doGetSkin();
- Q_SLOT void onSkinDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-
- void failResult(bool & flag);
- void succeedResult(bool & flag);
- void checkResult();
-
-protected:
- void beginActivity(Katabasis::Activity activity);
- void finishActivity();
- void clearTokens();
-
-protected:
- Katabasis::OAuth2 *m_oauth2 = nullptr;
- Yggdrasil *m_yggdrasil = nullptr;
-
- int m_requestsDone = 0;
- bool m_xboxProfileSucceeded = false;
- bool m_mcAuthSucceeded = false;
-
- QSet<int64_t> stsErrors;
- bool stsFailed = false;
-
- Katabasis::Activity m_activity = Katabasis::Activity::Idle;
- enum class AuthStage {
- Initial,
- UserAuth,
- XboxAuth,
- MinecraftProfile,
- MigrationEligibility,
- Skin,
- Complete
- } m_stage = AuthStage::Initial;
-
- void setStage(AuthStage stage);
-};
diff --git a/launcher/minecraft/auth/flows/AuthFlow.cpp b/launcher/minecraft/auth/flows/AuthFlow.cpp
new file mode 100644
index 00000000..4f78e8c3
--- /dev/null
+++ b/launcher/minecraft/auth/flows/AuthFlow.cpp
@@ -0,0 +1,71 @@
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QDebug>
+
+#include "AuthFlow.h"
+#include "katabasis/Globals.h"
+
+#include <Application.h>
+
+AuthFlow::AuthFlow(AccountData * data, QObject *parent) :
+ AccountTask(data, parent)
+{
+}
+
+void AuthFlow::succeed() {
+ m_data->validity_ = Katabasis::Validity::Certain;
+ changeState(
+ AccountTaskState::STATE_SUCCEEDED,
+ tr("Finished all authentication steps")
+ );
+}
+
+void AuthFlow::executeTask() {
+ if(m_currentStep) {
+ return;
+ }
+ changeState(AccountTaskState::STATE_WORKING, tr("Initializing"));
+ nextStep();
+}
+
+void AuthFlow::nextStep() {
+ if(m_steps.size() == 0) {
+ // we got to the end without an incident... assume this is all.
+ m_currentStep.reset();
+ succeed();
+ return;
+ }
+ m_currentStep = m_steps.front();
+ qDebug() << "AuthFlow:" << m_currentStep->describe();
+ m_steps.pop_front();
+ connect(m_currentStep.get(), &AuthStep::finished, this, &AuthFlow::stepFinished);
+ connect(m_currentStep.get(), &AuthStep::showVerificationUriAndCode, this, &AuthFlow::showVerificationUriAndCode);
+ connect(m_currentStep.get(), &AuthStep::hideVerificationUriAndCode, this, &AuthFlow::hideVerificationUriAndCode);
+
+ m_currentStep->perform();
+}
+
+
+QString AuthFlow::getStateMessage() const {
+ switch (m_taskState)
+ {
+ case AccountTaskState::STATE_WORKING: {
+ if(m_currentStep) {
+ return m_currentStep->describe();
+ }
+ else {
+ return tr("Working...");
+ }
+ }
+ default: {
+ return AccountTask::getStateMessage();
+ }
+ }
+}
+
+void AuthFlow::stepFinished(AccountTaskState resultingState, QString message) {
+ if(changeState(resultingState, message)) {
+ nextStep();
+ }
+}
diff --git a/launcher/minecraft/auth/flows/AuthFlow.h b/launcher/minecraft/auth/flows/AuthFlow.h
new file mode 100644
index 00000000..e067cc99
--- /dev/null
+++ b/launcher/minecraft/auth/flows/AuthFlow.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <QObject>
+#include <QList>
+#include <QVector>
+#include <QSet>
+#include <QNetworkReply>
+#include <QImage>
+
+#include <katabasis/DeviceFlow.h>
+
+#include "minecraft/auth/Yggdrasil.h"
+#include "minecraft/auth/AccountData.h"
+#include "minecraft/auth/AccountTask.h"
+#include "minecraft/auth/AuthStep.h"
+
+class AuthFlow : public AccountTask
+{
+ Q_OBJECT
+
+public:
+ explicit AuthFlow(AccountData * data, QObject *parent = 0);
+
+ Katabasis::Validity validity() {
+ return m_data->validity_;
+ };
+
+ QString getStateMessage() const override;
+
+ void executeTask() override;
+
+signals:
+ void activityChanged(Katabasis::Activity activity);
+
+private slots:
+ void stepFinished(AccountTaskState resultingState, QString message);
+
+protected:
+ void succeed();
+ void nextStep();
+
+protected:
+ QList<AuthStep::Ptr> m_steps;
+ AuthStep::Ptr m_currentStep;
+};
diff --git a/launcher/minecraft/auth/flows/MSA.cpp b/launcher/minecraft/auth/flows/MSA.cpp
new file mode 100644
index 00000000..416b8f2c
--- /dev/null
+++ b/launcher/minecraft/auth/flows/MSA.cpp
@@ -0,0 +1,37 @@
+#include "MSA.h"
+
+#include "minecraft/auth/steps/MSAStep.h"
+#include "minecraft/auth/steps/XboxUserStep.h"
+#include "minecraft/auth/steps/XboxAuthorizationStep.h"
+#include "minecraft/auth/steps/LauncherLoginStep.h"
+#include "minecraft/auth/steps/XboxProfileStep.h"
+#include "minecraft/auth/steps/EntitlementsStep.h"
+#include "minecraft/auth/steps/MinecraftProfileStep.h"
+#include "minecraft/auth/steps/GetSkinStep.h"
+
+MSASilent::MSASilent(AccountData* data, QObject* parent) : AuthFlow(data, parent) {
+ m_steps.append(new MSAStep(m_data, MSAStep::Action::Refresh));
+ m_steps.append(new XboxUserStep(m_data));
+ m_steps.append(new XboxAuthorizationStep(m_data, &m_data->xboxApiToken, "http://xboxlive.com", "Xbox"));
+ m_steps.append(new XboxAuthorizationStep(m_data, &m_data->mojangservicesToken, "rp://api.minecraftservices.com/", "Mojang"));
+ m_steps.append(new LauncherLoginStep(m_data));
+ m_steps.append(new XboxProfileStep(m_data));
+ m_steps.append(new EntitlementsStep(m_data));
+ m_steps.append(new MinecraftProfileStep(m_data));
+ m_steps.append(new GetSkinStep(m_data));
+}
+
+MSAInteractive::MSAInteractive(
+ AccountData* data,
+ QObject* parent
+) : AuthFlow(data, parent) {
+ m_steps.append(new MSAStep(m_data, MSAStep::Action::Login));
+ m_steps.append(new XboxUserStep(m_data));
+ m_steps.append(new XboxAuthorizationStep(m_data, &m_data->xboxApiToken, "http://xboxlive.com", "Xbox"));
+ m_steps.append(new XboxAuthorizationStep(m_data, &m_data->mojangservicesToken, "rp://api.minecraftservices.com/", "Mojang"));
+ m_steps.append(new LauncherLoginStep(m_data));
+ m_steps.append(new XboxProfileStep(m_data));
+ m_steps.append(new EntitlementsStep(m_data));
+ m_steps.append(new MinecraftProfileStep(m_data));
+ m_steps.append(new GetSkinStep(m_data));
+}
diff --git a/launcher/minecraft/auth/flows/MSA.h b/launcher/minecraft/auth/flows/MSA.h
new file mode 100644
index 00000000..14a4ff43
--- /dev/null
+++ b/launcher/minecraft/auth/flows/MSA.h
@@ -0,0 +1,22 @@
+#pragma once
+#include "AuthFlow.h"
+
+class MSAInteractive : public AuthFlow
+{
+ Q_OBJECT
+public:
+ explicit MSAInteractive(
+ AccountData *data,
+ QObject *parent = 0
+ );
+};
+
+class MSASilent : public AuthFlow
+{
+ Q_OBJECT
+public:
+ explicit MSASilent(
+ AccountData * data,
+ QObject *parent = 0
+ );
+};
diff --git a/launcher/minecraft/auth/flows/MSAInteractive.cpp b/launcher/minecraft/auth/flows/MSAInteractive.cpp
deleted file mode 100644
index 03beb279..00000000
--- a/launcher/minecraft/auth/flows/MSAInteractive.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "MSAInteractive.h"
-
-MSAInteractive::MSAInteractive(AccountData* data, QObject* parent) : AuthContext(data, parent) {}
-
-void MSAInteractive::executeTask() {
- m_requestsDone = 0;
- m_xboxProfileSucceeded = false;
- m_mcAuthSucceeded = false;
-
- initMSA();
-
- QVariantMap extraOpts;
- extraOpts["prompt"] = "select_account";
- m_oauth2->setExtraRequestParams(extraOpts);
-
- beginActivity(Katabasis::Activity::LoggingIn);
- m_oauth2->unlink();
- *m_data = AccountData();
- m_oauth2->link();
-}
diff --git a/launcher/minecraft/auth/flows/MSAInteractive.h b/launcher/minecraft/auth/flows/MSAInteractive.h
deleted file mode 100644
index 9556f254..00000000
--- a/launcher/minecraft/auth/flows/MSAInteractive.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-#include "AuthContext.h"
-
-class MSAInteractive : public AuthContext
-{
- Q_OBJECT
-public:
- explicit MSAInteractive(AccountData * data, QObject *parent = 0);
- void executeTask() override;
-};
diff --git a/launcher/minecraft/auth/flows/MSASilent.cpp b/launcher/minecraft/auth/flows/MSASilent.cpp
deleted file mode 100644
index 8ce43c1f..00000000
--- a/launcher/minecraft/auth/flows/MSASilent.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "MSASilent.h"
-
-MSASilent::MSASilent(AccountData* data, QObject* parent) : AuthContext(data, parent) {}
-
-void MSASilent::executeTask() {
- m_requestsDone = 0;
- m_xboxProfileSucceeded = false;
- m_mcAuthSucceeded = false;
-
- initMSA();
-
- beginActivity(Katabasis::Activity::Refreshing);
- if(!m_oauth2->refresh()) {
- finishActivity();
- }
-}
diff --git a/launcher/minecraft/auth/flows/MSASilent.h b/launcher/minecraft/auth/flows/MSASilent.h
deleted file mode 100644
index e1b3d43d..00000000
--- a/launcher/minecraft/auth/flows/MSASilent.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-#include "AuthContext.h"
-
-class MSASilent : public AuthContext
-{
- Q_OBJECT
-public:
- explicit MSASilent(AccountData * data, QObject *parent = 0);
- void executeTask() override;
-};
diff --git a/launcher/minecraft/auth/flows/Mojang.cpp b/launcher/minecraft/auth/flows/Mojang.cpp
new file mode 100644
index 00000000..4661dbe2
--- /dev/null
+++ b/launcher/minecraft/auth/flows/Mojang.cpp
@@ -0,0 +1,27 @@
+#include "Mojang.h"
+
+#include "minecraft/auth/steps/YggdrasilStep.h"
+#include "minecraft/auth/steps/MinecraftProfileStep.h"
+#include "minecraft/auth/steps/MigrationEligibilityStep.h"
+#include "minecraft/auth/steps/GetSkinStep.h"
+
+MojangRefresh::MojangRefresh(
+ AccountData *data,
+ QObject *parent
+) : AuthFlow(data, parent) {
+ m_steps.append(new YggdrasilStep(m_data, QString()));
+ m_steps.append(new MinecraftProfileStep(m_data));
+ m_steps.append(new MigrationEligibilityStep(m_data));
+ m_steps.append(new GetSkinStep(m_data));
+}
+
+MojangLogin::MojangLogin(
+ AccountData *data,
+ QString password,
+ QObject *parent
+): AuthFlow(data, parent), m_password(password) {
+ m_steps.append(new YggdrasilStep(m_data, m_password));
+ m_steps.append(new MinecraftProfileStep(m_data));
+ m_steps.append(new MigrationEligibilityStep(m_data));
+ m_steps.append(new GetSkinStep(m_data));
+}
diff --git a/launcher/minecraft/auth/flows/Mojang.h b/launcher/minecraft/auth/flows/Mojang.h
new file mode 100644
index 00000000..c09c81a8
--- /dev/null
+++ b/launcher/minecraft/auth/flows/Mojang.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "AuthFlow.h"
+
+class MojangRefresh : public AuthFlow
+{
+ Q_OBJECT
+public:
+ explicit MojangRefresh(
+ AccountData *data,
+ QObject *parent = 0
+ );
+};
+
+class MojangLogin : public AuthFlow
+{
+ Q_OBJECT
+public:
+ explicit MojangLogin(
+ AccountData *data,
+ QString password,
+ QObject *parent = 0
+ );
+
+private:
+ QString m_password;
+};
diff --git a/launcher/minecraft/auth/flows/MojangLogin.cpp b/launcher/minecraft/auth/flows/MojangLogin.cpp
deleted file mode 100644
index cca911b5..00000000
--- a/launcher/minecraft/auth/flows/MojangLogin.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "MojangLogin.h"
-
-MojangLogin::MojangLogin(AccountData* data, QString password, QObject* parent) : AuthContext(data, parent), m_password(password) {}
-
-void MojangLogin::executeTask() {
- m_requestsDone = 0;
- m_xboxProfileSucceeded = false;
- m_mcAuthSucceeded = false;
-
- initMojang();
-
- beginActivity(Katabasis::Activity::LoggingIn);
- m_yggdrasil->login(m_password);
-}
diff --git a/launcher/minecraft/auth/flows/MojangLogin.h b/launcher/minecraft/auth/flows/MojangLogin.h
deleted file mode 100644
index 2e765ae8..00000000
--- a/launcher/minecraft/auth/flows/MojangLogin.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-#include "AuthContext.h"
-
-class MojangLogin : public AuthContext
-{
- Q_OBJECT
-public:
- explicit MojangLogin(AccountData * data, QString password, QObject *parent = 0);
- void executeTask() override;
-
-private:
- QString m_password;
-};
diff --git a/launcher/minecraft/auth/flows/MojangRefresh.cpp b/launcher/minecraft/auth/flows/MojangRefresh.cpp
deleted file mode 100644
index af99175c..00000000
--- a/launcher/minecraft/auth/flows/MojangRefresh.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "MojangRefresh.h"
-
-MojangRefresh::MojangRefresh(AccountData* data, QObject* parent) : AuthContext(data, parent) {}
-
-void MojangRefresh::executeTask() {
- m_requestsDone = 0;
- m_xboxProfileSucceeded = false;
- m_mcAuthSucceeded = false;
-
- initMojang();
-
- beginActivity(Katabasis::Activity::Refreshing);
- m_yggdrasil->refresh();
-}
diff --git a/launcher/minecraft/auth/flows/MojangRefresh.h b/launcher/minecraft/auth/flows/MojangRefresh.h
deleted file mode 100644
index fb4facd5..00000000
--- a/launcher/minecraft/auth/flows/MojangRefresh.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-#include "AuthContext.h"
-
-class MojangRefresh : public AuthContext
-{
- Q_OBJECT
-public:
- explicit MojangRefresh(AccountData * data, QObject *parent = 0);
- void executeTask() override;
-};
diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.cpp b/launcher/minecraft/auth/steps/EntitlementsStep.cpp
new file mode 100644
index 00000000..f726244f
--- /dev/null
+++ b/launcher/minecraft/auth/steps/EntitlementsStep.cpp
@@ -0,0 +1,53 @@
+#include "EntitlementsStep.h"
+
+#include <QNetworkRequest>
+#include <QUuid>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+EntitlementsStep::EntitlementsStep(AccountData* data) : AuthStep(data) {}
+
+EntitlementsStep::~EntitlementsStep() noexcept = default;
+
+QString EntitlementsStep::describe() {
+ return tr("Determining game ownership.");
+}
+
+
+void EntitlementsStep::perform() {
+ auto uuid = QUuid::createUuid();
+ m_entitlementsRequestId = uuid.toString().remove('{').remove('}');
+ auto url = "https://api.minecraftservices.com/entitlements/license?requestId=" + m_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, &EntitlementsStep::onRequestDone);
+ requestor->get(request);
+ qDebug() << "Getting entitlements...";
+}
+
+void EntitlementsStep::rehydrate() {
+ // NOOP, for now. We only save bools and there's nothing to check.
+}
+
+void EntitlementsStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+#ifndef NDEBUG
+ qDebug() << data;
+#endif
+
+ // TODO: check presence of same entitlementsRequestId?
+ // TODO: validate JWTs?
+ Parsers::parseMinecraftEntitlements(data, m_data->minecraftEntitlement);
+
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got entitlements"));
+}
diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.h b/launcher/minecraft/auth/steps/EntitlementsStep.h
new file mode 100644
index 00000000..9412ae79
--- /dev/null
+++ b/launcher/minecraft/auth/steps/EntitlementsStep.h
@@ -0,0 +1,25 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class EntitlementsStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit EntitlementsStep(AccountData *data);
+ virtual ~EntitlementsStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+
+private:
+ QString m_entitlementsRequestId;
+};
diff --git a/launcher/minecraft/auth/steps/GetSkinStep.cpp b/launcher/minecraft/auth/steps/GetSkinStep.cpp
new file mode 100644
index 00000000..3521f8dc
--- /dev/null
+++ b/launcher/minecraft/auth/steps/GetSkinStep.cpp
@@ -0,0 +1,43 @@
+
+#include "GetSkinStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+GetSkinStep::GetSkinStep(AccountData* data) : AuthStep(data) {
+
+}
+
+GetSkinStep::~GetSkinStep() noexcept = default;
+
+QString GetSkinStep::describe() {
+ return tr("Getting skin.");
+}
+
+void GetSkinStep::perform() {
+ auto url = QUrl(m_data->minecraftProfile.skin.url);
+ QNetworkRequest request = QNetworkRequest(url);
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &GetSkinStep::onRequestDone);
+ requestor->get(request);
+}
+
+void GetSkinStep::rehydrate() {
+ // NOOP, for now.
+}
+
+void GetSkinStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ if (error == QNetworkReply::NoError) {
+ m_data->minecraftProfile.skin.data = data;
+ }
+ emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Got skin"));
+}
diff --git a/launcher/minecraft/auth/steps/GetSkinStep.h b/launcher/minecraft/auth/steps/GetSkinStep.h
new file mode 100644
index 00000000..6b97371e
--- /dev/null
+++ b/launcher/minecraft/auth/steps/GetSkinStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class GetSkinStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit GetSkinStep(AccountData *data);
+ virtual ~GetSkinStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp
new file mode 100644
index 00000000..c978bd07
--- /dev/null
+++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp
@@ -0,0 +1,78 @@
+#include "LauncherLoginStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+#include "minecraft/auth/AccountTask.h"
+
+LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) {
+
+}
+
+LauncherLoginStep::~LauncherLoginStep() noexcept = default;
+
+QString LauncherLoginStep::describe() {
+ return tr("Accessing Mojang services.");
+}
+
+void LauncherLoginStep::perform() {
+ 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(
+{
+ "xtoken": "XBL3.0 x=%1;%2",
+ "platform": "PC_LAUNCHER"
+}
+)XXX";
+ auto requestBody = mc_auth_template.arg(uhs, xToken);
+
+ 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, &LauncherLoginStep::onRequestDone);
+ requestor->post(request, requestBody.toUtf8());
+ qDebug() << "Getting Minecraft access token...";
+}
+
+void LauncherLoginStep::rehydrate() {
+ // TODO: check the token validity
+}
+
+void LauncherLoginStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ qDebug() << data;
+ if (error != QNetworkReply::NoError) {
+ qWarning() << "Reply error:" << error;
+#ifndef NDEBUG
+ qDebug() << data;
+#endif
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to get Minecraft access token: %1").arg(requestor->errorString_)
+ );
+ return;
+ }
+
+ if(!Parsers::parseMojangResponse(data, m_data->yggdrasilToken)) {
+ qWarning() << "Could not parse login_with_xbox response...";
+#ifndef NDEBUG
+ qDebug() << data;
+#endif
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to parse the Minecraft access token response.")
+ );
+ return;
+ }
+ emit finished(AccountTaskState::STATE_WORKING, tr(""));
+}
diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.h b/launcher/minecraft/auth/steps/LauncherLoginStep.h
new file mode 100644
index 00000000..e06a306f
--- /dev/null
+++ b/launcher/minecraft/auth/steps/LauncherLoginStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class LauncherLoginStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit LauncherLoginStep(AccountData *data);
+ virtual ~LauncherLoginStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
new file mode 100644
index 00000000..be711f7e
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -0,0 +1,111 @@
+#include "MSAStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+#include "Application.h"
+
+using OAuth2 = Katabasis::DeviceFlow;
+using Activity = Katabasis::Activity;
+
+MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) {
+ OAuth2::Options opts;
+ opts.scope = "XboxLive.signin offline_access";
+ 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";
+
+ // 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::activityChanged, this, &MSAStep::onOAuthActivityChanged);
+ connect(m_oauth2, &OAuth2::showVerificationUriAndCode, this, &MSAStep::showVerificationUriAndCode);
+}
+
+MSAStep::~MSAStep() noexcept = default;
+
+QString MSAStep::describe() {
+ return tr("Logging in with Microsoft account.");
+}
+
+
+void MSAStep::rehydrate() {
+ switch(m_action) {
+ case Refresh: {
+ // TODO: check the tokens and see if they are old (older than a day)
+ return;
+ }
+ case Login: {
+ // NOOP
+ return;
+ }
+ }
+}
+
+void MSAStep::perform() {
+ switch(m_action) {
+ case Refresh: {
+ m_oauth2->refresh();
+ return;
+ }
+ case Login: {
+ QVariantMap extraOpts;
+ extraOpts["prompt"] = "select_account";
+ m_oauth2->setExtraRequestParams(extraOpts);
+
+ *m_data = AccountData();
+ m_oauth2->login();
+ return;
+ }
+ }
+}
+
+void MSAStep::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();
+ 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
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got "));
+ return;
+ }
+ case Katabasis::Activity::FailedSoft: {
+ // NOTE: soft error in the first step means 'offline'
+ emit hideVerificationUriAndCode();
+ emit finished(AccountTaskState::STATE_OFFLINE, tr("Microsoft user authentication ended with a network error."));
+ return;
+ }
+ case Katabasis::Activity::FailedGone: {
+ emit hideVerificationUriAndCode();
+ emit finished(AccountTaskState::STATE_FAILED_GONE, tr("Microsoft user authentication failed - user no longer exists."));
+ return;
+ }
+ case Katabasis::Activity::FailedHard: {
+ emit hideVerificationUriAndCode();
+ emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Microsoft user authentication failed."));
+ return;
+ }
+ default: {
+ emit hideVerificationUriAndCode();
+ emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Microsoft user authentication completed with an unrecognized result."));
+ return;
+ }
+ }
+}
diff --git a/launcher/minecraft/auth/steps/MSAStep.h b/launcher/minecraft/auth/steps/MSAStep.h
new file mode 100644
index 00000000..49ba3542
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MSAStep.h
@@ -0,0 +1,32 @@
+
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+#include <katabasis/DeviceFlow.h>
+
+class MSAStep : public AuthStep {
+ Q_OBJECT
+public:
+ enum Action {
+ Refresh,
+ Login
+ };
+public:
+ explicit MSAStep(AccountData *data, Action action);
+ virtual ~MSAStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onOAuthActivityChanged(Katabasis::Activity activity);
+
+private:
+ Katabasis::DeviceFlow *m_oauth2 = nullptr;
+ Action m_action;
+};
diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp b/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp
new file mode 100644
index 00000000..f5b5637a
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp
@@ -0,0 +1,45 @@
+#include "MigrationEligibilityStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+MigrationEligibilityStep::MigrationEligibilityStep(AccountData* data) : AuthStep(data) {
+
+}
+
+MigrationEligibilityStep::~MigrationEligibilityStep() noexcept = default;
+
+QString MigrationEligibilityStep::describe() {
+ return tr("Checking for migration eligibility.");
+}
+
+void MigrationEligibilityStep::perform() {
+ auto url = QUrl("https://api.minecraftservices.com/rollout/v1/msamigration");
+ QNetworkRequest request = QNetworkRequest(url);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
+
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &MigrationEligibilityStep::onRequestDone);
+ requestor->get(request);
+}
+
+void MigrationEligibilityStep::rehydrate() {
+ // NOOP, for now. We only save bools and there's nothing to check.
+}
+
+void MigrationEligibilityStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ if (error == QNetworkReply::NoError) {
+ Parsers::parseRolloutResponse(data, m_data->canMigrateToMSA);
+ }
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got migration flags"));
+}
diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.h b/launcher/minecraft/auth/steps/MigrationEligibilityStep.h
new file mode 100644
index 00000000..b1bf9cbf
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MigrationEligibilityStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class MigrationEligibilityStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit MigrationEligibilityStep(AccountData *data);
+ virtual ~MigrationEligibilityStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
new file mode 100644
index 00000000..9fef99b0
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
@@ -0,0 +1,83 @@
+#include "MinecraftProfileStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+MinecraftProfileStep::MinecraftProfileStep(AccountData* data) : AuthStep(data) {
+
+}
+
+MinecraftProfileStep::~MinecraftProfileStep() noexcept = default;
+
+QString MinecraftProfileStep::describe() {
+ return tr("Fetching the Minecraft profile.");
+}
+
+
+void MinecraftProfileStep::perform() {
+ auto url = QUrl("https://api.minecraftservices.com/minecraft/profile");
+ QNetworkRequest request = QNetworkRequest(url);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
+
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &MinecraftProfileStep::onRequestDone);
+ requestor->get(request);
+}
+
+void MinecraftProfileStep::rehydrate() {
+ // NOOP, for now. We only save bools and there's nothing to check.
+}
+
+void MinecraftProfileStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+#ifndef NDEBUG
+ 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();
+ emit finished(
+ AccountTaskState::STATE_SUCCEEDED,
+ tr("Account has no Minecraft profile.")
+ );
+ return;
+ }
+ if (error != QNetworkReply::NoError) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Minecraft Java profile acquisition failed.")
+ );
+ return;
+ }
+ if(!Parsers::parseMinecraftProfile(data, m_data->minecraftProfile)) {
+ m_data->minecraftProfile = MinecraftProfile();
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Minecraft Java profile response could not be parsed")
+ );
+ return;
+ }
+
+ 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;
+ }
+ emit finished(
+ AccountTaskState::STATE_WORKING,
+ tr("Minecraft Java profile acquisition succeeded.")
+ );
+}
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.h b/launcher/minecraft/auth/steps/MinecraftProfileStep.h
new file mode 100644
index 00000000..8ef3395c
--- /dev/null
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class MinecraftProfileStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit MinecraftProfileStep(AccountData *data);
+ virtual ~MinecraftProfileStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp
new file mode 100644
index 00000000..07eeb7dc
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp
@@ -0,0 +1,158 @@
+#include "XboxAuthorizationStep.h"
+
+#include <QNetworkRequest>
+#include <QJsonParseError>
+#include <QJsonDocument>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+XboxAuthorizationStep::XboxAuthorizationStep(AccountData* data, Katabasis::Token *token, QString relyingParty, QString authorizationKind):
+ AuthStep(data),
+ m_token(token),
+ m_relyingParty(relyingParty),
+ m_authorizationKind(authorizationKind)
+{
+}
+
+XboxAuthorizationStep::~XboxAuthorizationStep() noexcept = default;
+
+QString XboxAuthorizationStep::describe() {
+ return tr("Getting authorization to access %1 services.").arg(m_authorizationKind);
+}
+
+void XboxAuthorizationStep::rehydrate() {
+ // FIXME: check if the tokens are good?
+}
+
+void XboxAuthorizationStep::perform() {
+ QString xbox_auth_template = R"XXX(
+{
+ "Properties": {
+ "SandboxId": "RETAIL",
+ "UserTokens": [
+ "%1"
+ ]
+ },
+ "RelyingParty": "%2",
+ "TokenType": "JWT"
+}
+)XXX";
+ auto xbox_auth_data = xbox_auth_template.arg(m_data->userToken.token, m_relyingParty);
+// http://xboxlive.com
+ QNetworkRequest request = QNetworkRequest(QUrl("https://xsts.auth.xboxlive.com/xsts/authorize"));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ request.setRawHeader("Accept", "application/json");
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &XboxAuthorizationStep::onRequestDone);
+ requestor->post(request, xbox_auth_data.toUtf8());
+ qDebug() << "Getting authorization token for " << m_relyingParty;
+}
+
+void XboxAuthorizationStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+#ifndef NDEBUG
+ qDebug() << data;
+#endif
+ if (error != QNetworkReply::NoError) {
+ qWarning() << "Reply error:" << error;
+ if(!processSTSError(error, data, headers)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to get authorization for %1 services. Error %1.").arg(m_authorizationKind, error)
+ );
+ }
+ return;
+ }
+
+ Katabasis::Token temp;
+ if(!Parsers::parseXTokenResponse(data, temp, m_authorizationKind)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Could not parse authorization response for access to %1 services.").arg(m_authorizationKind)
+ );
+ return;
+ }
+
+ if(temp.extra["uhs"] != m_data->userToken.extra["uhs"]) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Server has changed %1 authorization user hash in the reply. Something is wrong.").arg(m_authorizationKind)
+ );
+ return;
+ }
+ auto & token = *m_token;
+ token = temp;
+
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got authorization to access %1").arg(m_relyingParty));
+}
+
+
+bool XboxAuthorizationStep::processSTSError(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ if(error == QNetworkReply::AuthenticationRequiredError) {
+ QJsonParseError jsonError;
+ QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
+ if(jsonError.error) {
+ qWarning() << "Cannot parse error XSTS response as JSON: " << jsonError.errorString();
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Cannot parse %1 authorization error response as JSON: %2").arg(m_authorizationKind, jsonError.errorString())
+ );
+ return true;
+ }
+
+ int64_t errorCode = -1;
+ auto obj = doc.object();
+ if(!Parsers::getNumber(obj.value("XErr"), errorCode)) {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("XErr element is missing from %1 authorization error response.").arg(m_authorizationKind)
+ );
+ return true;
+ }
+ switch(errorCode) {
+ case 2148916233:{
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("This Microsoft account does not have an XBox Live profile. Buy the game on %1 first.")
+ .arg("<a href=\"https://www.minecraft.net/en-us/store/minecraft-java-edition\">minecraft.net</a>")
+ );
+ return true;
+ }
+ case 2148916235: {
+ // NOTE: this is the Grulovia error
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("XBox Live is not available in your country. You've been blocked.")
+ );
+ return true;
+ }
+ case 2148916238: {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("This Microsoft account is underaged and is not linked to a family.\n\nPlease set up your account according to %1.")
+ .arg("<a href=\"https://help.minecraft.net/hc/en-us/articles/4403181904525\">help.minecraft.net</a>")
+ );
+ return true;
+ }
+ default: {
+ emit finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("XSTS authentication ended with unrecognized error(s):\n\n%1").arg(errorCode)
+ );
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.h b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h
new file mode 100644
index 00000000..31e43bf0
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h
@@ -0,0 +1,34 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class XboxAuthorizationStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit XboxAuthorizationStep(AccountData *data, Katabasis::Token *token, QString relyingParty, QString authorizationKind);
+ virtual ~XboxAuthorizationStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private:
+ bool processSTSError(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+ );
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+
+private:
+ Katabasis::Token *m_token;
+ QString m_relyingParty;
+ QString m_authorizationKind;
+};
diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.cpp b/launcher/minecraft/auth/steps/XboxProfileStep.cpp
new file mode 100644
index 00000000..9f50138e
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxProfileStep.cpp
@@ -0,0 +1,73 @@
+#include "XboxProfileStep.h"
+
+#include <QNetworkRequest>
+#include <QUrlQuery>
+
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+XboxProfileStep::XboxProfileStep(AccountData* data) : AuthStep(data) {
+
+}
+
+XboxProfileStep::~XboxProfileStep() noexcept = default;
+
+QString XboxProfileStep::describe() {
+ return tr("Fetching Xbox profile.");
+}
+
+void XboxProfileStep::rehydrate() {
+ // NOOP, for now. We only save bools and there's nothing to check.
+}
+
+void XboxProfileStep::perform() {
+ auto url = QUrl("https://profile.xboxlive.com/users/me/profile/settings");
+ QUrlQuery q;
+ q.addQueryItem(
+ "settings",
+ "GameDisplayName,AppDisplayName,AppDisplayPicRaw,GameDisplayPicRaw,"
+ "PublicGamerpic,ShowUserAsAvatar,Gamerscore,Gamertag,ModernGamertag,ModernGamertagSuffix,"
+ "UniqueModernGamertag,AccountTier,TenureLevel,XboxOneRep,"
+ "PreferredColor,Location,Bio,Watermarks,"
+ "RealName,RealNameOverride,IsQuarantined"
+ );
+ url.setQuery(q);
+
+ QNetworkRequest request = QNetworkRequest(url);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ request.setRawHeader("Accept", "application/json");
+ request.setRawHeader("x-xbl-contract-version", "3");
+ request.setRawHeader("Authorization", QString("XBL3.0 x=%1;%2").arg(m_data->userToken.extra["uhs"].toString(), m_data->xboxApiToken.token).toUtf8());
+ AuthRequest *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &XboxProfileStep::onRequestDone);
+ requestor->get(request);
+ qDebug() << "Getting Xbox profile...";
+}
+
+void XboxProfileStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ if (error != QNetworkReply::NoError) {
+ qWarning() << "Reply error:" << error;
+#ifndef NDEBUG
+ qDebug() << data;
+#endif
+ finished(
+ AccountTaskState::STATE_FAILED_SOFT,
+ tr("Failed to retrieve the Xbox profile.")
+ );
+ return;
+ }
+
+#ifndef NDEBUG
+ qDebug() << "XBox profile: " << data;
+#endif
+
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got Xbox profile"));
+}
diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.h b/launcher/minecraft/auth/steps/XboxProfileStep.h
new file mode 100644
index 00000000..7a0c5873
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxProfileStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class XboxProfileStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit XboxProfileStep(AccountData *data);
+ virtual ~XboxProfileStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/XboxUserStep.cpp b/launcher/minecraft/auth/steps/XboxUserStep.cpp
new file mode 100644
index 00000000..a38a28e4
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxUserStep.cpp
@@ -0,0 +1,68 @@
+#include "XboxUserStep.h"
+
+#include <QNetworkRequest>
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+
+XboxUserStep::XboxUserStep(AccountData* data) : AuthStep(data) {
+
+}
+
+XboxUserStep::~XboxUserStep() noexcept = default;
+
+QString XboxUserStep::describe() {
+ return tr("Logging in as an Xbox user.");
+}
+
+
+void XboxUserStep::rehydrate() {
+ // NOOP, for now. We only save bools and there's nothing to check.
+}
+
+void XboxUserStep::perform() {
+ QString xbox_auth_template = R"XXX(
+{
+ "Properties": {
+ "AuthMethod": "RPS",
+ "SiteName": "user.auth.xboxlive.com",
+ "RpsTicket": "d=%1"
+ },
+ "RelyingParty": "http://auth.xboxlive.com",
+ "TokenType": "JWT"
+}
+)XXX";
+ auto xbox_auth_data = xbox_auth_template.arg(m_data->msaToken.token);
+
+ QNetworkRequest request = QNetworkRequest(QUrl("https://user.auth.xboxlive.com/user/authenticate"));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ request.setRawHeader("Accept", "application/json");
+ auto *requestor = new AuthRequest(this);
+ connect(requestor, &AuthRequest::finished, this, &XboxUserStep::onRequestDone);
+ requestor->post(request, xbox_auth_data.toUtf8());
+ qDebug() << "First layer of XBox auth ... commencing.";
+}
+
+void XboxUserStep::onRequestDone(
+ QNetworkReply::NetworkError error,
+ QByteArray data,
+ QList<QNetworkReply::RawHeaderPair> headers
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ if (error != QNetworkReply::NoError) {
+ qWarning() << "Reply error:" << error;
+ emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed."));
+ return;
+ }
+
+ Katabasis::Token temp;
+ if(!Parsers::parseXTokenResponse(data, temp, "UToken")) {
+ qWarning() << "Could not parse user authentication response...";
+ emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication response could not be understood."));
+ return;
+ }
+ m_data->userToken = temp;
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got Xbox user token"));
+}
diff --git a/launcher/minecraft/auth/steps/XboxUserStep.h b/launcher/minecraft/auth/steps/XboxUserStep.h
new file mode 100644
index 00000000..83e9405f
--- /dev/null
+++ b/launcher/minecraft/auth/steps/XboxUserStep.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+
+class XboxUserStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit XboxUserStep(AccountData *data);
+ virtual ~XboxUserStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
+};
diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.cpp b/launcher/minecraft/auth/steps/YggdrasilStep.cpp
new file mode 100644
index 00000000..4c6b1624
--- /dev/null
+++ b/launcher/minecraft/auth/steps/YggdrasilStep.cpp
@@ -0,0 +1,51 @@
+#include "YggdrasilStep.h"
+
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
+#include "minecraft/auth/Yggdrasil.h"
+
+YggdrasilStep::YggdrasilStep(AccountData* data, QString password) : AuthStep(data), m_password(password) {
+ m_yggdrasil = new Yggdrasil(m_data, this);
+
+ connect(m_yggdrasil, &Task::failed, this, &YggdrasilStep::onAuthFailed);
+ connect(m_yggdrasil, &Task::succeeded, this, &YggdrasilStep::onAuthSucceeded);
+}
+
+YggdrasilStep::~YggdrasilStep() noexcept = default;
+
+QString YggdrasilStep::describe() {
+ return tr("Logging in with Mojang account.");
+}
+
+void YggdrasilStep::rehydrate() {
+ // NOOP, for now.
+}
+
+void YggdrasilStep::perform() {
+ if(m_password.size()) {
+ m_yggdrasil->login(m_password);
+ }
+ else {
+ m_yggdrasil->refresh();
+ }
+}
+
+void YggdrasilStep::onAuthSucceeded() {
+ emit finished(AccountTaskState::STATE_WORKING, tr("Logged in with Mojang"));
+}
+
+void YggdrasilStep::onAuthFailed() {
+ // TODO: hook these in again, expand to MSA
+ // m_error = m_yggdrasil->m_error;
+ // m_aborted = m_yggdrasil->m_aborted;
+
+ auto state = m_yggdrasil->taskState();
+ QString errorMessage = tr("Mojang user authentication failed.");
+
+ // NOTE: soft error in the first step means 'offline'
+ if(state == AccountTaskState::STATE_FAILED_SOFT) {
+ state = AccountTaskState::STATE_OFFLINE;
+ errorMessage = tr("Mojang user authentication ended with a network error.");
+ }
+ emit finished(state, errorMessage);
+}
diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.h b/launcher/minecraft/auth/steps/YggdrasilStep.h
new file mode 100644
index 00000000..ebafb8e5
--- /dev/null
+++ b/launcher/minecraft/auth/steps/YggdrasilStep.h
@@ -0,0 +1,28 @@
+#pragma once
+#include <QObject>
+
+#include "QObjectPtr.h"
+#include "minecraft/auth/AuthStep.h"
+
+class Yggdrasil;
+
+class YggdrasilStep : public AuthStep {
+ Q_OBJECT
+
+public:
+ explicit YggdrasilStep(AccountData *data, QString password);
+ virtual ~YggdrasilStep() noexcept;
+
+ void perform() override;
+ void rehydrate() override;
+
+ QString describe() override;
+
+private slots:
+ void onAuthSucceeded();
+ void onAuthFailed();
+
+private:
+ Yggdrasil *m_yggdrasil = nullptr;
+ QString m_password;
+};
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..f467ec06 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;
}
@@ -122,6 +122,11 @@ QString LegacyInstance::binRoot() const
return FS::PathCombine(gameRoot(), "bin");
}
+QString LegacyInstance::modsRoot() const {
+ return FS::PathCombine(gameRoot(), "mods");
+}
+
+
QString LegacyInstance::jarModsDir() const
{
return FS::PathCombine(instanceRoot(), "instMods");
@@ -137,11 +142,6 @@ QString LegacyInstance::savesDir() const
return FS::PathCombine(gameRoot(), "saves");
}
-QString LegacyInstance::loaderModsDir() const
-{
- return FS::PathCombine(gameRoot(), "mods");
-}
-
QString LegacyInstance::coreModsDir() const
{
return FS::PathCombine(gameRoot(), "coremods");
diff --git a/launcher/minecraft/legacy/LegacyInstance.h b/launcher/minecraft/legacy/LegacyInstance.h
index ac2a8543..298543f7 100644
--- a/launcher/minecraft/legacy/LegacyInstance.h
+++ b/launcher/minecraft/legacy/LegacyInstance.h
@@ -45,11 +45,13 @@ public:
QString savesDir() const;
QString texturePacksDir() const;
QString jarModsDir() const;
- QString loaderModsDir() const;
QString coreModsDir() const;
QString resourceDir() const;
- virtual QString instanceConfigFolder() const override;
+
+ QString instanceConfigFolder() const override;
+
QString gameRoot() const override; // Path to the instance's minecraft directory.
+ QString modsRoot() const override; // Path to the instance's minecraft directory.
QString binRoot() const; // Path to the instance's minecraft bin directory.
/// Get the curent base jar of this instance. By default, it's the
@@ -93,7 +95,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..e49c166a 100644
--- a/launcher/minecraft/services/CapeChange.cpp
+++ b/launcher/minecraft/services/CapeChange.cpp
@@ -1,22 +1,24 @@
#include "CapeChange.h"
+
#include <QNetworkRequest>
#include <QHttpMultiPart>
-#include <Env.h>
-CapeChange::CapeChange(QObject *parent, AuthSessionPtr session, QString cape)
- : Task(parent), m_capeId(cape), m_session(session)
+#include "Application.h"
+
+CapeChange::CapeChange(QObject *parent, QString token, QString cape)
+ : Task(parent), m_capeId(cape), m_token(token)
{
}
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());
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit());
+ 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()));
@@ -25,12 +27,12 @@ void CapeChange::setCape(QString& cape) {
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);
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit());
+ 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..185d69b6 100644
--- a/launcher/minecraft/services/CapeChange.h
+++ b/launcher/minecraft/services/CapeChange.h
@@ -3,14 +3,14 @@
#include <QFile>
#include <QtNetwork/QtNetwork>
#include <memory>
-#include <minecraft/auth/AuthSession.h>
#include "tasks/Task.h"
+#include "QObjectPtr.h"
class CapeChange : public Task
{
Q_OBJECT
public:
- CapeChange(QObject *parent, AuthSessionPtr session, QString capeId);
+ CapeChange(QObject *parent, QString token, QString capeId);
virtual ~CapeChange() {}
private:
@@ -19,8 +19,8 @@ private:
private:
QString m_capeId;
- AuthSessionPtr m_session;
- std::shared_ptr<QNetworkReply> m_reply;
+ QString m_token;
+ 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..cce8364e 100644
--- a/launcher/minecraft/services/SkinDelete.cpp
+++ b/launcher/minecraft/services/SkinDelete.cpp
@@ -1,19 +1,21 @@
#include "SkinDelete.h"
+
#include <QNetworkRequest>
#include <QHttpMultiPart>
-#include <Env.h>
-SkinDelete::SkinDelete(QObject *parent, AuthSessionPtr session)
- : Task(parent), m_session(session)
+#include "Application.h"
+
+SkinDelete::SkinDelete(QObject *parent, QString token)
+ : Task(parent), m_token(token)
{
}
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);
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit());
+ 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..83a84685 100644
--- a/launcher/minecraft/services/SkinDelete.h
+++ b/launcher/minecraft/services/SkinDelete.h
@@ -2,22 +2,20 @@
#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
{
Q_OBJECT
public:
- SkinDelete(QObject *parent, AuthSessionPtr session);
+ SkinDelete(QObject *parent, QString token);
virtual ~SkinDelete() = default;
private:
- AuthSessionPtr m_session;
- std::shared_ptr<QNetworkReply> m_reply;
+ QString m_token;
+ shared_qobject_ptr<QNetworkReply> m_reply;
protected:
virtual void executeTask();
@@ -26,4 +24,3 @@ public slots:
void downloadError(QNetworkReply::NetworkError);
void downloadFinished();
};
-
diff --git a/launcher/minecraft/services/SkinUpload.cpp b/launcher/minecraft/services/SkinUpload.cpp
index 4e5a1698..7c2e8337 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) {
@@ -14,15 +16,15 @@ QByteArray getVariant(SkinUpload::Model model) {
}
}
-SkinUpload::SkinUpload(QObject *parent, AuthSessionPtr session, QByteArray skin, SkinUpload::Model model)
- : Task(parent), m_model(model), m_skin(skin), m_session(session)
+SkinUpload::SkinUpload(QObject *parent, QString token, QByteArray skin, SkinUpload::Model model)
+ : Task(parent), m_model(model), m_skin(skin), m_token(token)
{
}
void SkinUpload::executeTask()
{
QNetworkRequest request(QUrl("https://api.minecraftservices.com/minecraft/profile/skins"));
- request.setRawHeader("Authorization", QString("Bearer %1").arg(m_session->access_token).toLocal8Bit());
+ request.setRawHeader("Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit());
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart skin;
@@ -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..2c1f0a2e 100644
--- a/launcher/minecraft/services/SkinUpload.h
+++ b/launcher/minecraft/services/SkinUpload.h
@@ -3,10 +3,9 @@
#include <QFile>
#include <QtNetwork/QtNetwork>
#include <memory>
-#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
{
@@ -19,14 +18,14 @@ public:
};
// Note this class takes ownership of the file.
- SkinUpload(QObject *parent, AuthSessionPtr session, QByteArray skin, Model model = STEVE);
+ SkinUpload(QObject *parent, QString token, QByteArray skin, Model model = STEVE);
virtual ~SkinUpload() {}
private:
Model m_model;
QByteArray m_skin;
- AuthSessionPtr m_session;
- std::shared_ptr<QNetworkReply> m_reply;
+ QString m_token;
+ 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/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index 83505635..52921512 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -3,5 +3,6 @@
<qresource prefix="/backgrounds">
<file alias="kitteh">catbgrnd2.png</file>
<file alias="catmas">catmas.png</file>
+ <file alias="cattiversary">cattiversary.png</file>
</qresource>
</RCC>
diff --git a/launcher/resources/backgrounds/cattiversary.png b/launcher/resources/backgrounds/cattiversary.png
new file mode 100644
index 00000000..09a36566
--- /dev/null
+++ b/launcher/resources/backgrounds/cattiversary.png
Binary files differ
diff --git a/launcher/resources/sources/burfcat_hat.png b/launcher/resources/sources/burfcat_hat.png
new file mode 100644
index 00000000..a378c1fb
--- /dev/null
+++ b/launcher/resources/sources/burfcat_hat.png
Binary files differ
diff --git a/launcher/resources/sources/cattiversary.xcf b/launcher/resources/sources/cattiversary.xcf
new file mode 100644
index 00000000..0026cd35
--- /dev/null
+++ b/launcher/resources/sources/cattiversary.xcf
Binary files differ
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..576258eb 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
@@ -37,6 +39,20 @@ struct Language
updated = (key == defaultLangCode);
}
+ QString languageName() const {
+ QString result;
+ if(key == "ja_KANJI") {
+ result = locale.nativeLanguageName() + u8" (漢字)";
+ }
+ else if(key == "es_UY") {
+ result = u8"español de Latinoamérica";
+ }
+ else {
+ result = locale.nativeLanguageName();
+ }
+ return result;
+ }
+
float percentTranslated() const
{
if (total == 0)
@@ -119,10 +135,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;
@@ -338,7 +354,7 @@ QVariant TranslationsModel::data(const QModelIndex& index, int role) const
{
case Column::Language:
{
- return lang.locale.nativeLanguageName();
+ return lang.languageName();
}
case Column::Completeness:
{
@@ -558,13 +574,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 +617,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 +631,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..b06f3d5a 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 {
@@ -208,8 +211,10 @@ public:
TranslatedAction actionEditInstNotes;
TranslatedAction actionEditInstance;
TranslatedAction actionWorlds;
+ TranslatedAction actionMods;
TranslatedAction actionViewSelectedInstFolder;
TranslatedAction actionViewSelectedMCFolder;
+ TranslatedAction actionViewSelectedModsFolder;
TranslatedAction actionDeleteInstance;
TranslatedAction actionConfig_Folder;
TranslatedAction actionCAT;
@@ -278,7 +283,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 +296,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 +304,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 +316,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 +325,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 +338,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 +348,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 +358,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 +367,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 +380,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 +391,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 +402,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 +411,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 +424,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 +451,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 +483,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);
@@ -527,6 +532,13 @@ public:
all_actions.append(&actionEditInstNotes);
instanceToolBar->addAction(actionEditInstNotes);
+ actionMods = TranslatedAction(MainWindow);
+ actionMods->setObjectName(QStringLiteral("actionMods"));
+ actionMods.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Mods"));
+ actionMods.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View the mods of this instance."));
+ all_actions.append(&actionMods);
+ instanceToolBar->addAction(actionMods);
+
actionWorlds = TranslatedAction(MainWindow);
actionWorlds->setObjectName(QStringLiteral("actionWorlds"));
actionWorlds.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Worlds"));
@@ -557,6 +569,15 @@ public:
all_actions.append(&actionViewSelectedMCFolder);
instanceToolBar->addAction(actionViewSelectedMCFolder);
+ /*
+ actionViewSelectedModsFolder = TranslatedAction(MainWindow);
+ actionViewSelectedModsFolder->setObjectName(QStringLiteral("actionViewSelectedModsFolder"));
+ actionViewSelectedModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Mods Folder"));
+ actionViewSelectedModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the selected instance's mods folder in a file browser."));
+ all_actions.append(&actionViewSelectedModsFolder);
+ instanceToolBar->addAction(actionViewSelectedModsFolder);
+ */
+
actionConfig_Folder = TranslatedAction(MainWindow);
actionConfig_Folder->setObjectName(QStringLiteral("actionConfig_Folder"));
actionConfig_Folder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Config Folder"));
@@ -589,7 +610,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 +627,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 +702,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 +731,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 +757,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 +786,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 +797,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 +813,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 +827,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 +855,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 +865,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 +897,6 @@ QMenu * MainWindow::createPopupMenu()
void MainWindow::konamiTriggered()
{
- // ENV.enableFeature("NewModsPage");
qDebug() << "Super Secret Mode ACTIVATED!";
}
@@ -982,16 +1002,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 +1028,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 +1044,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 +1072,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 +1095,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 +1123,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 +1223,7 @@ void MainWindow::updateNewsLabel()
void MainWindow::updateAvailable(GoUpdate::Status status)
{
- if(!LAUNCHER->updatesAreAllowed())
+ if(!APPLICATION->updatesAreAllowed())
{
updateNotAvailable();
return;
@@ -1239,7 +1269,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 +1282,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 +1308,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 +1322,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 {
@@ -1310,8 +1340,18 @@ void MainWindow::setCatBackground(bool enabled)
if (enabled)
{
QDateTime now = QDateTime::currentDateTime();
+ QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QString cat = (non_stupid_abs(now.daysTo(xmas)) <= 4) ? "catmas" : "kitteh";
+ QString cat;
+ if(non_stupid_abs(now.daysTo(xmas)) <= 4) {
+ cat = "catmas";
+ }
+ else if (non_stupid_abs(now.daysTo(birthday)) <= 12) {
+ cat = "cattiversary";
+ }
+ else {
+ cat = "kitteh";
+ }
view->setStyleSheet(QString(R"(
InstanceView
{
@@ -1350,7 +1390,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 +1407,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 +1415,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 +1461,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 +1519,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 +1529,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 +1538,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 +1547,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 +1563,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 +1573,7 @@ void MainWindow::on_actionChangeInstGroup_triggered()
name = name.simplified();
if (ok)
{
- LAUNCHER->instances()->setInstanceGroup(instId, name);
+ APPLICATION->instances()->setInstanceGroup(instId, name);
}
}
@@ -1555,25 +1595,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 +1629,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 +1640,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 +1656,37 @@ 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_actionMods_triggered()
+{
+ APPLICATION->showInstanceWindow(m_selectedInstance, "mods");
}
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 +1740,7 @@ void MainWindow::on_actionDeleteInstance_triggered()
)->exec();
if (response == QMessageBox::Yes)
{
- LAUNCHER->instances()->deleteInstance(id);
+ APPLICATION->instances()->deleteInstance(id);
}
}
@@ -1739,12 +1784,25 @@ void MainWindow::on_actionViewSelectedMCFolder_triggered()
}
}
+void MainWindow::on_actionViewSelectedModsFolder_triggered()
+{
+ if (m_selectedInstance)
+ {
+ QString str = m_selectedInstance->modsRoot();
+ if (!FS::ensureFilePathExists(str))
+ {
+ // TODO: report error
+ return;
+ }
+ DesktopServices::openDirectory(QDir(str).absolutePath());
+ }
+}
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 +1821,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 +1836,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 +1877,12 @@ void MainWindow::instanceChanged(const QModelIndex &current, 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 +1905,12 @@ void MainWindow::instanceChanged(const QModelIndex &current, 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 +1942,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 +1986,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..e462c524 100644
--- a/launcher/MainWindow.h
+++ b/launcher/ui/MainWindow.h
@@ -93,6 +93,8 @@ private slots:
void on_actionViewSelectedMCFolder_triggered();
+ void on_actionViewSelectedModsFolder_triggered();
+
void refreshInstances();
void on_actionViewCentralModsFolder_triggered();
@@ -133,6 +135,8 @@ private slots:
void on_actionEditInstNotes_triggered();
+ void on_actionMods_triggered();
+
void on_actionWorlds_triggered();
void on_actionScreenshots_triggered();
@@ -166,7 +170,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..194315a7 100644
--- a/launcher/dialogs/LoginDialog.cpp
+++ b/launcher/ui/dialogs/LoginDialog.cpp
@@ -43,7 +43,7 @@ void LoginDialog::accept()
// Setup the login task and start it
m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text());
- m_loginTask = m_account->login(nullptr, ui->passTextBox->text());
+ m_loginTask = m_account->login(ui->passTextBox->text());
connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this, &LoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
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..f46aa3b9 100644
--- a/launcher/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -37,7 +37,7 @@ int MSALoginDialog::exec() {
// Setup the login task and start it
m_account = MinecraftAccount::createBlankMSA();
- m_loginTask = m_account->loginMSA(nullptr);
+ m_loginTask = m_account->loginMSA();
connect(m_loginTask.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this, &MSALoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
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..76b6af49
--- /dev/null
+++ b/launcher/ui/dialogs/ProfileSetupDialog.cpp
@@ -0,0 +1,256 @@
+/* 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/AuthRequest.h"
+#include "minecraft/auth/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
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ 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
+) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
+ 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..6a5a324f 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()
{
@@ -19,16 +20,6 @@ void SkinUploadDialog::on_buttonBox_rejected()
void SkinUploadDialog::on_buttonBox_accepted()
{
- AuthSessionPtr session = std::make_shared<AuthSession>();
- auto login = m_acct->refresh(session);
- ProgressDialog prog(this);
- if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted)
- {
- //FIXME: recover with password prompt
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to login!"), QMessageBox::Warning)->exec();
- close();
- return;
- }
QString fileName;
QString input = ui->skinPathTextBox->text();
QRegExp urlPrefixMatcher("^([a-z]+)://.+$");
@@ -90,11 +81,12 @@ void SkinUploadDialog::on_buttonBox_accepted()
{
model = SkinUpload::ALEX;
}
+ ProgressDialog prog(this);
SequentialTask skinUpload;
- skinUpload.addTask(std::make_shared<SkinUpload>(this, session, FS::read(fileName), model));
+ skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, m_acct->accessToken(), 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, m_acct->accessToken(), 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..d3eb2655 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);
}
}
}
@@ -169,13 +170,7 @@ void AccountListPage::on_actionRefresh_triggered() {
if (selection.size() > 0) {
QModelIndex selected = selection.first();
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
- AuthSessionPtr session = std::make_shared<AuthSession>();
- auto task = account->refresh(session);
- if (task) {
- ProgressDialog progDialog(this);
- progDialog.execWithTask(task.get());
- // TODO: respond to results of the task
- }
+ m_accounts->requestRefresh(account->internalId());
}
}
@@ -187,27 +182,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 +217,6 @@ void AccountListPage::updateButtonStates()
ui->actionNoDefault->setEnabled(true);
ui->actionNoDefault->setChecked(false);
}
-
}
void AccountListPage::on_actionUploadSkin_triggered()
@@ -237,15 +238,9 @@ void AccountListPage::on_actionDeleteSkin_triggered()
return;
QModelIndex selected = selection.first();
- AuthSessionPtr session = std::make_shared<AuthSession>();
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
- auto login = account->refresh(session);
ProgressDialog prog(this);
- if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted) {
- CustomMessageBox::selectable(this, tr("Skin Delete"), tr("Failed to login!"), QMessageBox::Warning)->exec();
- return;
- }
- auto deleteSkinTask = std::make_shared<SkinDelete>(this, session);
+ auto deleteSkinTask = std::make_shared<SkinDelete>(this, account->accessToken());
if (prog.execWithTask((Task*)deleteSkinTask.get()) != QDialog::Accepted) {
CustomMessageBox::selectable(this, tr("Skin Delete"), tr("Failed to delete current skin!"), QMessageBox::Warning)->exec();
return;
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..6e57909b 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
{
@@ -216,9 +215,6 @@ void VersionPage::updateVersionControls()
bool supportsFabric = minecraftVersion >= Version("1.14");
ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric);
- bool supportsForge = minecraftVersion <= Version("1.16.5");
- ui->actionInstall_Forge->setEnabled(controlsEnabled && supportsForge);
-
bool supportsLiteLoader = minecraftVersion <= Version("1.12.2");
ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && supportsLiteLoader);
@@ -297,7 +293,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 +303,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 +391,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 +416,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 +445,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 +490,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 +610,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/ui/widgets/ErrorFrame.cpp b/launcher/ui/widgets/ErrorFrame.cpp
new file mode 100644
index 00000000..b3e41036
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.cpp
@@ -0,0 +1,134 @@
+/* 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 <QMessageBox>
+#include <QtGui>
+
+#include "ErrorFrame.h"
+#include "ui_ErrorFrame.h"
+
+#include "ui/dialogs/CustomMessageBox.h"
+
+void ErrorFrame::clear()
+{
+ setTitle(QString());
+ setDescription(QString());
+}
+
+ErrorFrame::ErrorFrame(QWidget *parent) :
+ QFrame(parent),
+ ui(new Ui::ErrorFrame)
+{
+ ui->setupUi(this);
+ ui->label_Description->setHidden(true);
+ ui->label_Title->setHidden(true);
+ updateHiddenState();
+}
+
+ErrorFrame::~ErrorFrame()
+{
+ delete ui;
+}
+
+void ErrorFrame::updateHiddenState()
+{
+ if(ui->label_Description->isHidden() && ui->label_Title->isHidden())
+ {
+ setHidden(true);
+ }
+ else
+ {
+ setHidden(false);
+ }
+}
+
+void ErrorFrame::setTitle(QString text)
+{
+ if(text.isEmpty())
+ {
+ ui->label_Title->setHidden(true);
+ }
+ else
+ {
+ ui->label_Title->setText(text);
+ ui->label_Title->setHidden(false);
+ }
+ updateHiddenState();
+}
+
+void ErrorFrame::setDescription(QString text)
+{
+ if(text.isEmpty())
+ {
+ ui->label_Description->setHidden(true);
+ updateHiddenState();
+ return;
+ }
+ else
+ {
+ ui->label_Description->setHidden(false);
+ updateHiddenState();
+ }
+ ui->label_Description->setToolTip("");
+ QString intermediatetext = text.trimmed();
+ bool prev(false);
+ QChar rem('\n');
+ QString finaltext;
+ finaltext.reserve(intermediatetext.size());
+ foreach(const QChar& c, intermediatetext)
+ {
+ if(c == rem && prev){
+ continue;
+ }
+ prev = c == rem;
+ finaltext += c;
+ }
+ QString labeltext;
+ labeltext.reserve(300);
+ if(finaltext.length() > 290)
+ {
+ ui->label_Description->setOpenExternalLinks(false);
+ ui->label_Description->setTextFormat(Qt::TextFormat::RichText);
+ desc = text;
+ // This allows injecting HTML here.
+ labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>");
+ QObject::connect(ui->label_Description, &QLabel::linkActivated, this, &ErrorFrame::ellipsisHandler);
+ }
+ else
+ {
+ ui->label_Description->setTextFormat(Qt::TextFormat::PlainText);
+ labeltext.append(finaltext);
+ }
+ ui->label_Description->setText(labeltext);
+}
+
+void ErrorFrame::ellipsisHandler(const QString &link)
+{
+ if(!currentBox)
+ {
+ currentBox = CustomMessageBox::selectable(this, QString(), desc);
+ connect(currentBox, &QMessageBox::finished, this, &ErrorFrame::boxClosed);
+ currentBox->show();
+ }
+ else
+ {
+ currentBox->setText(desc);
+ }
+}
+
+void ErrorFrame::boxClosed(int result)
+{
+ currentBox = nullptr;
+}
diff --git a/launcher/ui/widgets/ErrorFrame.h b/launcher/ui/widgets/ErrorFrame.h
new file mode 100644
index 00000000..d5069a14
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.h
@@ -0,0 +1,49 @@
+/* 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 <QFrame>
+
+namespace Ui
+{
+class ErrorFrame;
+}
+
+class ErrorFrame : public QFrame
+{
+ Q_OBJECT
+
+public:
+ explicit ErrorFrame(QWidget *parent = 0);
+ ~ErrorFrame();
+
+ void setTitle(QString text);
+ void setDescription(QString text);
+
+ void clear();
+
+public slots:
+ void ellipsisHandler(const QString& link );
+ void boxClosed(int result);
+
+private:
+ void updateHiddenState();
+
+private:
+ Ui::ErrorFrame *ui;
+ QString desc;
+ class QMessageBox * currentBox = nullptr;
+};
diff --git a/launcher/ui/widgets/ErrorFrame.ui b/launcher/ui/widgets/ErrorFrame.ui
new file mode 100644
index 00000000..0bb56743
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ErrorFrame</class>
+ <widget class="QFrame" name="ErrorFrame">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>527</width>
+ <height>113</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>120</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_Title">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </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>
+ <item>
+ <widget class="QLabel" name="label_Description">
+ <property name="toolTip">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </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>
+ <resources/>
+ <connections/>
+</ui>
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());