From 441ab7eedcb8fe120a7f934684ed5545cdd7a4b6 Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Wed, 13 Oct 2021 01:59:25 +0200 Subject: NOISSUE debranding for real, initial work This is probably very broken on macOS and Windows and will need a lot of work to complete fully. --- .gitignore | 4 +- .gitmodules | 2 + BUILD.md | 2 +- CMakeLists.txt | 165 +-- README.md | 32 +- buildconfig/BuildConfig.cpp.in | 42 +- changelog.md | 4 +- launcher/BaseInstance.h | 2 +- launcher/CMakeLists.txt | 78 +- launcher/Env.h | 2 +- launcher/GuiUtil.cpp | 4 +- launcher/InstanceList.cpp | 2 +- launcher/InstanceProxyModel.cpp | 6 +- launcher/InstanceWindow.cpp | 18 +- launcher/LaunchController.cpp | 10 +- launcher/Launcher.cpp | 1493 ++++++++++++++++++++ launcher/Launcher.h | 235 +++ launcher/Launcher.in | 94 ++ launcher/MainWindow.cpp | 198 +-- launcher/MultiMC.cpp | 1493 -------------------- launcher/MultiMC.h | 235 --- launcher/VersionProxyModel.cpp | 8 +- launcher/dialogs/AboutDialog.cpp | 4 +- launcher/dialogs/CopyInstanceDialog.cpp | 10 +- launcher/dialogs/ExportInstanceDialog.cpp | 4 +- launcher/dialogs/IconPickerDialog.cpp | 12 +- launcher/dialogs/NewComponentDialog.cpp | 4 +- launcher/dialogs/NewInstanceDialog.cpp | 24 +- launcher/dialogs/ProfileSelectDialog.cpp | 4 +- launcher/dialogs/UpdateDialog.cpp | 12 +- launcher/dialogs/VersionSelectDialog.cpp | 2 +- launcher/main.cpp | 12 +- launcher/minecraft/OneSixVersionFormat.cpp | 18 +- launcher/package/linux/MultiMC | 93 -- launcher/package/linux/multimc.desktop | 11 - launcher/pagedialog/PageDialog.cpp | 6 +- launcher/pages/global/AccountListPage.cpp | 4 +- launcher/pages/global/AccountListPage.h | 6 +- launcher/pages/global/CustomCommandsPage.cpp | 4 +- launcher/pages/global/CustomCommandsPage.h | 4 +- launcher/pages/global/ExternalToolsPage.cpp | 18 +- launcher/pages/global/ExternalToolsPage.h | 6 +- launcher/pages/global/JavaPage.cpp | 8 +- launcher/pages/global/JavaPage.h | 4 +- launcher/pages/global/LanguagePage.cpp | 2 +- launcher/pages/global/LanguagePage.h | 4 +- launcher/pages/global/LauncherPage.cpp | 466 ++++++ launcher/pages/global/LauncherPage.h | 103 ++ launcher/pages/global/LauncherPage.ui | 584 ++++++++ launcher/pages/global/MinecraftPage.cpp | 6 +- launcher/pages/global/MinecraftPage.h | 4 +- launcher/pages/global/MultiMCPage.cpp | 466 ------ launcher/pages/global/MultiMCPage.h | 103 -- launcher/pages/global/MultiMCPage.ui | 584 -------- launcher/pages/global/PasteEEPage.cpp | 6 +- launcher/pages/global/PasteEEPage.h | 4 +- launcher/pages/global/ProxyPage.cpp | 6 +- launcher/pages/global/ProxyPage.h | 4 +- launcher/pages/instance/GameOptionsPage.h | 4 +- launcher/pages/instance/InstanceSettingsPage.cpp | 14 +- launcher/pages/instance/InstanceSettingsPage.h | 4 +- launcher/pages/instance/LegacyUpgradePage.cpp | 6 +- launcher/pages/instance/LegacyUpgradePage.h | 4 +- launcher/pages/instance/LogPage.cpp | 6 +- launcher/pages/instance/LogPage.h | 4 +- launcher/pages/instance/ModFolderPage.cpp | 4 +- launcher/pages/instance/ModFolderPage.h | 4 +- launcher/pages/instance/NotesPage.h | 6 +- launcher/pages/instance/OtherLogsPage.cpp | 4 +- launcher/pages/instance/OtherLogsPage.h | 4 +- launcher/pages/instance/ScreenshotsPage.cpp | 4 +- launcher/pages/instance/ScreenshotsPage.h | 4 +- launcher/pages/instance/ServersPage.cpp | 4 +- launcher/pages/instance/ServersPage.h | 4 +- launcher/pages/instance/VersionPage.cpp | 18 +- launcher/pages/instance/WorldListPage.cpp | 8 +- launcher/pages/instance/WorldListPage.h | 4 +- launcher/pages/modplatform/ImportPage.cpp | 2 +- launcher/pages/modplatform/ImportPage.h | 4 +- launcher/pages/modplatform/VanillaPage.cpp | 2 +- launcher/pages/modplatform/VanillaPage.h | 4 +- .../pages/modplatform/atlauncher/AtlListModel.cpp | 4 +- launcher/pages/modplatform/atlauncher/AtlPage.cpp | 2 +- launcher/pages/modplatform/atlauncher/AtlPage.h | 4 +- launcher/pages/modplatform/flame/FlameModel.cpp | 4 +- launcher/pages/modplatform/flame/FlamePage.cpp | 2 +- launcher/pages/modplatform/flame/FlamePage.h | 4 +- launcher/pages/modplatform/ftb/FtbListModel.cpp | 4 +- launcher/pages/modplatform/ftb/FtbPage.h | 4 +- .../pages/modplatform/legacy_ftb/ListModel.cpp | 4 +- launcher/pages/modplatform/legacy_ftb/Page.cpp | 2 +- launcher/pages/modplatform/legacy_ftb/Page.h | 4 +- .../pages/modplatform/technic/TechnicModel.cpp | 4 +- launcher/pages/modplatform/technic/TechnicPage.cpp | 2 +- launcher/pages/modplatform/technic/TechnicPage.h | 4 +- launcher/resources/MultiMC.icns | Bin 782703 -> 0 bytes launcher/resources/MultiMC.ico | Bin 55224 -> 0 bytes launcher/resources/MultiMC.manifest | 31 - launcher/resources/multimc.rc | 29 - launcher/setupwizard/AnalyticsWizardPage.cpp | 6 +- launcher/setupwizard/JavaWizardPage.cpp | 6 +- launcher/setupwizard/LanguageWizardPage.cpp | 6 +- launcher/setupwizard/SetupWizard.cpp | 2 +- launcher/themes/ITheme.cpp | 6 +- launcher/translations/TranslationsModel.cpp | 2 +- launcher/widgets/JavaSettingsWidget.cpp | 12 +- launcher/widgets/LanguageSelectionWidget.cpp | 8 +- launcher/widgets/PageContainer.cpp | 10 +- libraries/classparser/CMakeLists.txt | 6 +- libraries/iconfix/CMakeLists.txt | 12 +- libraries/quazip | 2 +- libraries/rainbow/CMakeLists.txt | 8 +- notsecrets/CMakeLists.txt | 5 + notsecrets/Launcher.icns | Bin 0 -> 304757 bytes notsecrets/Launcher.ico | Bin 0 -> 102134 bytes notsecrets/Launcher.manifest | 31 + notsecrets/genicons.sh | 18 + notsecrets/launcher.rc | 29 + notsecrets/logo.svg | 274 ++++ secrets/multimc.rc | 29 + 120 files changed, 3862 insertions(+), 3581 deletions(-) create mode 100644 launcher/Launcher.cpp create mode 100644 launcher/Launcher.h create mode 100755 launcher/Launcher.in delete mode 100644 launcher/MultiMC.cpp delete mode 100644 launcher/MultiMC.h delete mode 100755 launcher/package/linux/MultiMC delete mode 100755 launcher/package/linux/multimc.desktop create mode 100644 launcher/pages/global/LauncherPage.cpp create mode 100644 launcher/pages/global/LauncherPage.h create mode 100644 launcher/pages/global/LauncherPage.ui delete mode 100644 launcher/pages/global/MultiMCPage.cpp delete mode 100644 launcher/pages/global/MultiMCPage.h delete mode 100644 launcher/pages/global/MultiMCPage.ui delete mode 100644 launcher/resources/MultiMC.icns delete mode 100644 launcher/resources/MultiMC.ico delete mode 100644 launcher/resources/MultiMC.manifest delete mode 100644 launcher/resources/multimc.rc create mode 100644 notsecrets/Launcher.icns create mode 100644 notsecrets/Launcher.ico create mode 100644 notsecrets/Launcher.manifest create mode 100755 notsecrets/genicons.sh create mode 100644 notsecrets/launcher.rc create mode 100644 notsecrets/logo.svg create mode 100644 secrets/multimc.rc diff --git a/.gitignore b/.gitignore index 6b716252..84bf1676 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,5 @@ tags #OSX Stuff .DS_Store -branding -secrets +branding/ +secrets/ diff --git a/.gitmodules b/.gitmodules index bd51ef80..04a561c2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,8 @@ [submodule "depends/libnbtplusplus"] path = libraries/libnbtplusplus url = https://github.com/MultiMC/libnbtplusplus.git + pushurl = git@github.com:MultiMC/libnbtplusplus.git [submodule "libraries/quazip"] path = libraries/quazip url = https://github.com/MultiMC/quazip.git + pushurl = git@github.com:MultiMC/quazip.git diff --git a/BUILD.md b/BUILD.md index de97433b..faa9fa85 100644 --- a/BUILD.md +++ b/BUILD.md @@ -197,7 +197,7 @@ cmake \ -DCMAKE_INSTALL_PREFIX:PATH="../dist/" \ -DCMAKE_PREFIX_PATH="/path/to/Qt5.6/" \ -DQt5_DIR="/path/to/Qt5.6/" \ - -DMultiMC_LAYOUT=mac-bundle \ + -DLauncher_LAYOUT=mac-bundle \ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \ .. make install diff --git a/CMakeLists.txt b/CMakeLists.txt index 44028f76..e4aae98b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,14 +2,14 @@ cmake_minimum_required(VERSION 3.1) string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD) if(IS_IN_SOURCE_BUILD) - message(FATAL_ERROR "You are building MultiMC in-source. Please separate the build tree from the source tree.") + message(FATAL_ERROR "You are building the Launcher in-source. Please separate the build tree from the source tree.") endif() if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if(CMAKE_HOST_SYSTEM_VERSION MATCHES ".*[Mm]icrosoft.*" OR CMAKE_HOST_SYSTEM_VERSION MATCHES ".*WSL.*" ) - message(FATAL_ERROR "Building MultiMC is not supported in Linux-on-Windows distributions.") + message(FATAL_ERROR "Building the Launcher is not supported in Linux-on-Windows distributions.") endif() endif() @@ -18,7 +18,7 @@ if(WIN32) cmake_policy(SET CMP0020 OLD) endif() -project(MultiMC) +project(Launcher) enable_testing() @@ -50,61 +50,61 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type") ##################################### Set Application options ##################################### ######## Set URLs ######## -set(MultiMC_NEWS_RSS_URL "https://multimc.org/rss.xml" CACHE STRING "URL to fetch MultiMC's news RSS feed from.") +set(Launcher_NEWS_RSS_URL "https://multimc.org/rss.xml" CACHE STRING "URL to fetch Launcher's news RSS feed from.") ######## Set version numbers ######## -set(MultiMC_VERSION_MAJOR 0) -set(MultiMC_VERSION_MINOR 6) -set(MultiMC_VERSION_HOTFIX 13) +set(Launcher_VERSION_MAJOR 0) +set(Launcher_VERSION_MINOR 6) +set(Launcher_VERSION_HOTFIX 13) # Build number -set(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") +set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") # Build platform. -set(MultiMC_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") +set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") # Channel list URL -set(MultiMC_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") +set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") # Notification URL -set(MultiMC_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") +set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") # The metadata server -set(MultiMC_META_URL "https://meta.multimc.org/v1/" CACHE STRING "URL to fetch MultiMC's meta files from.") +set(Launcher_META_URL "https://meta.multimc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") # paste.ee API key -set(MultiMC_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE STRING "API key you can get from paste.ee when you register an account") +set(Launcher_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE STRING "API key you can get from paste.ee when you register an account") # Imgur API Client ID -set(MultiMC_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") +set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") # Google analytics ID -set(MultiMC_ANALYTICS_ID "UA-87731965-2" CACHE STRING "ID you can get from Google analytics") +set(Launcher_ANALYTICS_ID "UA-87731965-2" CACHE STRING "ID you can get from Google analytics") # Bug tracker URL -set(MultiMC_BUG_TRACKER_URL "" CACHE STRING "URL for the bug tracker.") +set(Launcher_BUG_TRACKER_URL "" CACHE STRING "URL for the bug tracker.") # Discord URL -set(MultiMC_DISCORD_URL "" CACHE STRING "URL for the Discord guild.") +set(Launcher_DISCORD_URL "" CACHE STRING "URL for the Discord guild.") # Subreddit URL -set(MultiMC_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.") +set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.") - -option(MultiMC_EMBED_SECRETS "Determines whether to embed secrets. Secrets are separate and non-public." OFF) +# Use the secrets library or a public stub? +option(Launcher_EMBED_SECRETS "Determines whether to embed secrets. Secrets are separate and non-public." OFF) #### Check the current Git commit and branch include(GetGitRevisionDescription) -get_git_head_revision(MultiMC_GIT_REFSPEC MultiMC_GIT_COMMIT) +get_git_head_revision(Launcher_GIT_REFSPEC Launcher_GIT_COMMIT) -message(STATUS "Git commit: ${MultiMC_GIT_COMMIT}") -message(STATUS "Git refspec: ${MultiMC_GIT_REFSPEC}") +message(STATUS "Git commit: ${Launcher_GIT_COMMIT}") +message(STATUS "Git refspec: ${Launcher_GIT_REFSPEC}") -set(MultiMC_RELEASE_VERSION_NAME "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}") +set(Launcher_RELEASE_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}") #### Custom target to just print the version. -add_custom_target(version echo "Version: ${MultiMC_RELEASE_VERSION_NAME}") -add_custom_target(tcversion echo "\\#\\#teamcity[setParameter name=\\'env.MULTIMC_VERSION\\' value=\\'${MultiMC_RELEASE_VERSION_NAME}\\']") +add_custom_target(version echo "Version: ${Launcher_RELEASE_VERSION_NAME}") +add_custom_target(tcversion echo "\\#\\#teamcity[setParameter name=\\'env.LAUNCHER_VERSION\\' value=\\'${Launcher_RELEASE_VERSION_NAME}\\']") ################################ 3rd Party Libs ################################ @@ -129,47 +129,55 @@ if (Qt5_POSITION_INDEPENDENT_CODE) SET(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() +####################################### Secrets ####################################### + +if(Launcher_EMBED_SECRETS) + add_subdirectory(secrets) +else() + add_subdirectory(notsecrets) +endif() + ####################################### Install layout ####################################### # How to install the build results -set(MultiMC_LAYOUT "auto" CACHE STRING "The layout for MultiMC installation (auto, win-bundle, lin-bundle, lin-nodeps, lin-system, mac-bundle)") -set_property(CACHE MultiMC_LAYOUT PROPERTY STRINGS auto win-bundle lin-bundle lin-nodeps lin-system mac-bundle) +set(Launcher_LAYOUT "auto" CACHE STRING "The layout for the launcher installation (auto, win-bundle, lin-nodeps, mac-bundle)") +set_property(CACHE Launcher_LAYOUT PROPERTY STRINGS auto win-bundle lin-nodeps mac-bundle) -if(MultiMC_LAYOUT STREQUAL "auto") +if(Launcher_LAYOUT STREQUAL "auto") if(UNIX AND APPLE) - set(MultiMC_LAYOUT_REAL "mac-bundle") + set(Launcher_LAYOUT_REAL "mac-bundle") elseif(UNIX) - set(MultiMC_LAYOUT_REAL "lin-nodeps") + set(Launcher_LAYOUT_REAL "lin-nodeps") elseif(WIN32) - set(MultiMC_LAYOUT_REAL "win-bundle") + set(Launcher_LAYOUT_REAL "win-bundle") else() message(FATAL_ERROR "Cannot choose a sensible install layout for your platform.") endif() else() - set(MultiMC_LAYOUT_REAL ${MultiMC_LAYOUT}) + set(Launcher_LAYOUT_REAL ${Launcher_LAYOUT}) endif() -if(MultiMC_LAYOUT_REAL STREQUAL "mac-bundle") - set(BINARY_DEST_DIR "MultiMC.app/Contents/MacOS") - set(LIBRARY_DEST_DIR "MultiMC.app/Contents/MacOS") - set(PLUGIN_DEST_DIR "MultiMC.app/Contents/MacOS") - set(RESOURCES_DEST_DIR "MultiMC.app/Contents/Resources") - set(JARS_DEST_DIR "MultiMC.app/Contents/MacOS/jars") +if(Launcher_LAYOUT_REAL STREQUAL "mac-bundle") + set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(LIBRARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(PLUGIN_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources") + set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars") set(BUNDLE_DEST_DIR ".") # Apps to bundle - set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app") + set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") # Mac bundle settings - set(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC") - set(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.multimc.MultiMC5") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}") - set(MACOSX_BUNDLE_ICON_FILE MultiMC.icns) - set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 MultiMC Contributors") + set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") + set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: Minecraft launcher and management utility.") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.multimc.${Launcher_Name}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") + set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) + set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 ${Launcher_Copyright}") # directories to look for dependencies set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) @@ -178,32 +186,9 @@ if(MultiMC_LAYOUT_REAL STREQUAL "mac-bundle") set(INSTALL_BUNDLE "full") # Add the icon - install(FILES launcher/resources/MultiMC.icns DESTINATION ${RESOURCES_DEST_DIR}) - -elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-bundle") - set(BINARY_DEST_DIR "bin") - set(LIBRARY_DEST_DIR "bin") - set(PLUGIN_DEST_DIR "plugins") - set(BUNDLE_DEST_DIR ".") - set(RESOURCES_DEST_DIR ".") - set(JARS_DEST_DIR "bin/jars") - - # Apps to bundle - set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC") - - # directories to look for dependencies - set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR}) - # install as bundle - set(INSTALL_BUNDLE "full") - - # Set RPATH - SET(MultiMC_BINARY_RPATH "$ORIGIN/") - - # Install basic runner script - install(PROGRAMS launcher/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR}) - -elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-nodeps") +elseif(Launcher_LAYOUT_REAL STREQUAL "lin-nodeps") set(BINARY_DEST_DIR "bin") set(LIBRARY_DEST_DIR "bin") set(PLUGIN_DEST_DIR "plugins") @@ -215,28 +200,13 @@ elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-nodeps") set(INSTALL_BUNDLE "nodeps") # Set RPATH - SET(MultiMC_BINARY_RPATH "$ORIGIN/") + SET(Launcher_BINARY_RPATH "$ORIGIN/") # Install basic runner script - install(PROGRAMS launcher/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR}) - -elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-system") - set(MultiMC_APP_BINARY_NAME "multimc" CACHE STRING "Name of the MultiMC binary") - set(MultiMC_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory") - set(MultiMC_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory") - set(MultiMC_SHARE_DEST_DIR "share/multimc" CACHE STRING "Path to the shared data directory") - set(JARS_DEST_DIR "${MultiMC_SHARE_DEST_DIR}/jars") - - set(BINARY_DEST_DIR ${MultiMC_BINARY_DEST_DIR}) - set(LIBRARY_DEST_DIR ${MultiMC_LIBRARY_DEST_DIR}) - - MESSAGE(STATUS "Compiling for linux system with ${MultiMC_SHARE_DEST_DIR} and MULTIMC_LINUX_DATADIR") - SET(MultiMC_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DMULTIMC_LINUX_DATADIR") + configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY) + install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION ${BUNDLE_DEST_DIR} RENAME ${Launcher_Name}) - # install as bundle with no dependencies included - set(INSTALL_BUNDLE "nodeps") - -elseif(MultiMC_LAYOUT_REAL STREQUAL "win-bundle") +elseif(Launcher_LAYOUT_REAL STREQUAL "win-bundle") set(BINARY_DEST_DIR ".") set(LIBRARY_DEST_DIR ".") set(PLUGIN_DEST_DIR ".") @@ -245,7 +215,7 @@ elseif(MultiMC_LAYOUT_REAL STREQUAL "win-bundle") set(JARS_DEST_DIR "jars") # Apps to bundle - set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe") + set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.exe") # directories to look for dependencies set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) @@ -264,7 +234,7 @@ set_directory_properties(PROPERTIES EP_BASE External) option(NBT_BUILD_SHARED "Build NBT shared library" ON) option(NBT_USE_ZLIB "Build NBT library with zlib support" OFF) option(NBT_BUILD_TESTS "Build NBT library tests" OFF) #FIXME: fix unit tests. -set(NBT_NAME MultiMC_nbt++) +set(NBT_NAME Launcher_nbt++) set(NBT_DEST_DIR ${LIBRARY_DEST_DIR}) add_subdirectory(libraries/libnbtplusplus) @@ -287,12 +257,5 @@ add_subdirectory(libraries/katabasis) # An OAuth2 library that tried to do too m add_subdirectory(buildconfig) -if(MultiMC_EMBED_SECRETS) - add_subdirectory(secrets) -else() - add_subdirectory(notsecrets) -endif() - - # NOTE: this must always be last to appease the CMake deity of quirky install command evaluation order. add_subdirectory(launcher) diff --git a/README.md b/README.md index 92260d5e..84a1e4c4 100644 --- a/README.md +++ b/README.md @@ -48,33 +48,33 @@ Unless required by applicable law or agreed to in writing, software distributed ## Build status ### Linux (Intel32) - -Build: + +Build: - -Deploy: + +Deploy: ### Linux (AMD64) - -Build: + +Build: - -Deploy: + +Deploy: ### macOS (AMD64) - -Build: + +Build: - -Deploy: + +Deploy: ### Windows (Intel32) - -Build: + +Build: - -Deploy: + +Deploy: diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index d9f4d1f1..1b223b5d 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -6,19 +6,19 @@ const Config BuildConfig; Config::Config() { // Version information - VERSION_MAJOR = @MultiMC_VERSION_MAJOR@; - VERSION_MINOR = @MultiMC_VERSION_MINOR@; - VERSION_HOTFIX = @MultiMC_VERSION_HOTFIX@; - VERSION_BUILD = @MultiMC_VERSION_BUILD@; - - BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@"; - UPDATER_BASE = "@MultiMC_UPDATER_BASE@"; - ANALYTICS_ID = "@MultiMC_ANALYTICS_ID@"; - NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@"; - FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@"; - - GIT_COMMIT = "@MultiMC_GIT_COMMIT@"; - GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@"; + VERSION_MAJOR = @Launcher_VERSION_MAJOR@; + VERSION_MINOR = @Launcher_VERSION_MINOR@; + VERSION_HOTFIX = @Launcher_VERSION_HOTFIX@; + VERSION_BUILD = @Launcher_VERSION_BUILD@; + + BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; + UPDATER_BASE = "@Launcher_UPDATER_BASE@"; + ANALYTICS_ID = "@Launcher_ANALYTICS_ID@"; + NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@"; + FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@"; + + GIT_COMMIT = "@Launcher_GIT_COMMIT@"; + GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; if(GIT_REFSPEC.startsWith("refs/heads/") && !UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty() && VERSION_BUILD >= 0) { VERSION_CHANNEL = GIT_REFSPEC; @@ -30,15 +30,15 @@ Config::Config() VERSION_CHANNEL = QObject::tr("custom"); } - VERSION_STR = "@MultiMC_VERSION_STRING@"; - NEWS_RSS_URL = "@MultiMC_NEWS_RSS_URL@"; - PASTE_EE_KEY = "@MultiMC_PASTE_EE_API_KEY@"; - IMGUR_CLIENT_ID = "@MultiMC_IMGUR_CLIENT_ID@"; - META_URL = "@MultiMC_META_URL@"; + VERSION_STR = "@Launcher_VERSION_STRING@"; + NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@"; + PASTE_EE_KEY = "@Launcher_PASTE_EE_API_KEY@"; + IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; + META_URL = "@Launcher_META_URL@"; - BUG_TRACKER_URL = "@MultiMC_BUG_TRACKER_URL@"; - DISCORD_URL = "@MultiMC_DISCORD_URL@"; - SUBREDDIT_URL = "@MultiMC_SUBREDDIT_URL@"; + BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; + DISCORD_URL = "@Launcher_DISCORD_URL@"; + SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@"; } QString Config::printableVersionString() const diff --git a/changelog.md b/changelog.md index 97454d7f..e864a4c7 100644 --- a/changelog.md +++ b/changelog.md @@ -1121,7 +1121,7 @@ Fluffy and functional! - GH-1275: Server resource pack folder is created on launch. - This is a workaround for Minecraft bug MCL-3732. - GH-1320: Improve compatibility with non-Oracle Java. - - GH-1355: MMC environment will no longer leak into Minecraft after MultiMC updates itself. + - GH-1355: LAUNCHER environment will no longer leak into Minecraft after MultiMC updates itself. - Minecraft log: - Java exception detection in Minecraft logs has been improved. @@ -1166,7 +1166,7 @@ Fluffy and functional! - GH-1069, GH-1100: `LD_LIBRARY_PATH` and `LD_PRELOAD` environment variables supplied to MultiMC now don't affect MultiMC but affect the launched game. This means you can use something like the Steam overlay in MultiMC instances on Linux. - If you need to use these variables for MultiMC itself, you can use `MMC_LIBRARY_PATH` and `MMC_PRELOAD` instead. + If you need to use these variables for MultiMC itself, you can use `LAUNCHER_LIBRARY_PATH` and `LAUNCHER_PRELOAD` instead. - GH-1389: External processes (like folder views, editors, etc.) are now started in a way that prevents the MultiMC environment to be reused by them. - GH-1355: If `LD_LIBRARY_PATH` contains any of MultiMC's internal folders, this will not propagate to started processes. diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 8c08dc05..51258933 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -78,7 +78,7 @@ public: */ void invalidate(); - /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to + /// The instance's ID. The ID SHALL be determined by LAUNCHER internally. The ID IS guaranteed to /// be unique. virtual QString id() const; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 4ec6a7d1..d1216f86 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -88,13 +88,13 @@ set(CORE_SOURCES add_unit_test(FileSystem SOURCES FileSystem_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic DATA testdata ) add_unit_test(GZip SOURCES GZip_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) set(PATHMATCHER_SOURCES @@ -158,13 +158,13 @@ set(UPDATE_SOURCES add_unit_test(UpdateChecker SOURCES updater/UpdateChecker_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic DATA updater/testdata ) add_unit_test(DownloadTask SOURCES updater/DownloadTask_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic DATA updater/testdata ) @@ -337,14 +337,14 @@ set(MINECRAFT_SOURCES add_unit_test(GradleSpecifier SOURCES minecraft/GradleSpecifier_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) add_executable(PackageManifest mojang/PackageManifest_test.cpp ) target_link_libraries(PackageManifest - MultiMC_logic + Launcher_logic Qt5::Test ) target_include_directories(PackageManifest @@ -358,25 +358,25 @@ add_test( add_unit_test(MojangVersionFormat SOURCES minecraft/MojangVersionFormat_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic DATA minecraft/testdata ) add_unit_test(Library SOURCES minecraft/Library_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) # FIXME: shares data with FileSystem test add_unit_test(ModFolderModel SOURCES minecraft/mod/ModFolderModel_test.cpp DATA testdata - LIBS MultiMC_logic + LIBS Launcher_logic ) add_unit_test(ParseUtils SOURCES minecraft/ParseUtils_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) # the screenshots feature @@ -414,7 +414,7 @@ set(SETTINGS_SOURCES add_unit_test(INIFile SOURCES settings/INIFile_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) set(JAVA_SOURCES @@ -437,7 +437,7 @@ set(JAVA_SOURCES add_unit_test(JavaVersion SOURCES java/JavaVersion_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) set(TRANSLATIONS_SOURCES @@ -523,7 +523,7 @@ set(ATLAUNCHER_SOURCES add_unit_test(Index SOURCES meta/Index_test.cpp - LIBS MultiMC_logic + LIBS Launcher_logic ) ################################ COMPILE ################################ @@ -557,8 +557,8 @@ set(LOGIC_SOURCES SET(MULTIMC_SOURCES # Application base - MultiMC.h - MultiMC.cpp + Launcher.h + Launcher.cpp UpdateController.cpp UpdateController.h @@ -678,8 +678,8 @@ SET(MULTIMC_SOURCES pages/global/LanguagePage.h pages/global/MinecraftPage.cpp pages/global/MinecraftPage.h - pages/global/MultiMCPage.cpp - pages/global/MultiMCPage.h + pages/global/LauncherPage.cpp + pages/global/LauncherPage.h pages/global/ProxyPage.cpp pages/global/ProxyPage.h pages/global/PasteEEPage.cpp @@ -831,7 +831,7 @@ SET(MULTIMC_UIS pages/global/ExternalToolsPage.ui pages/global/JavaPage.ui pages/global/MinecraftPage.ui - pages/global/MultiMCPage.ui + pages/global/LauncherPage.ui pages/global/ProxyPage.ui pages/global/PasteEEPage.ui @@ -891,11 +891,11 @@ qt5_wrap_ui(MULTIMC_UI ${MULTIMC_UIS}) qt5_add_resources(MULTIMC_RESOURCES ${MULTIMC_QRCS}) # Add executable -add_library(MultiMC_logic STATIC ${LOGIC_SOURCES} ${MULTIMC_SOURCES} ${MULTIMC_UI} ${MULTIMC_RESOURCES}) -target_link_libraries(MultiMC_logic +add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${MULTIMC_SOURCES} ${MULTIMC_UI} ${MULTIMC_RESOURCES}) +target_link_libraries(Launcher_logic systeminfo - MultiMC_quazip - MultiMC_classparser + Launcher_quazip + Launcher_classparser ${NBT_NAME} ${ZLIB_LIBRARIES} optional-bare @@ -903,46 +903,46 @@ target_link_libraries(MultiMC_logic BuildConfig Katabasis ) -target_link_libraries(MultiMC_logic +target_link_libraries(Launcher_logic Qt5::Core Qt5::Xml Qt5::Network Qt5::Concurrent Qt5::Gui ) -target_link_libraries(MultiMC_logic - MultiMC_iconfix +target_link_libraries(Launcher_logic + Launcher_iconfix ${QUAZIP_LIBRARIES} hoedown - MultiMC_rainbow + Launcher_rainbow LocalPeer ganalytics ) -add_executable(MultiMC MACOSX_BUNDLE WIN32 main.cpp ${MULTIMC_RCS}) -target_link_libraries(MultiMC MultiMC_logic) +target_link_libraries(Launcher_logic secrets) -if(DEFINED MultiMC_APP_BINARY_NAME) - set_target_properties(MultiMC PROPERTIES OUTPUT_NAME "${MultiMC_APP_BINARY_NAME}") +add_executable(${Launcher_Name} MACOSX_BUNDLE WIN32 main.cpp ${MULTIMC_RCS}) +target_link_libraries(${Launcher_Name} Launcher_logic) + +if(DEFINED Launcher_APP_BINARY_NAME) + set_target_properties(${Launcher_Name} PROPERTIES OUTPUT_NAME "${Launcher_APP_BINARY_NAME}") endif() -if(DEFINED MultiMC_BINARY_RPATH) - SET_TARGET_PROPERTIES(MultiMC PROPERTIES INSTALL_RPATH "${MultiMC_BINARY_RPATH}") +if(DEFINED Launcher_BINARY_RPATH) + SET_TARGET_PROPERTIES(${Launcher_Name} PROPERTIES INSTALL_RPATH "${Launcher_BINARY_RPATH}") endif() -if(DEFINED MultiMC_APP_BINARY_DEFS) - target_compile_definitions(MultiMC PRIVATE ${MultiMC_APP_BINARY_DEFS}) - target_compile_definitions(MultiMC_logic PRIVATE ${MultiMC_APP_BINARY_DEFS}) +if(DEFINED Launcher_APP_BINARY_DEFS) + target_compile_definitions(${Launcher_Name} PRIVATE ${Launcher_APP_BINARY_DEFS}) + target_compile_definitions(Launcher_logic PRIVATE ${Launcher_APP_BINARY_DEFS}) endif() -install(TARGETS MultiMC +install(TARGETS ${Launcher_Name} BUNDLE DESTINATION ${BUNDLE_DEST_DIR} COMPONENT Runtime LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime ) -target_link_libraries(MultiMC_logic secrets) - -#### The MultiMC bundle mess! #### +#### The bundle mess! #### # Bundle utilities are used to complete the portable packages - they add all the libraries that would otherwise be missing on the target system. # NOTE: it seems that this absolutely has to be here, and nowhere else. if(INSTALL_BUNDLE STREQUAL "full") diff --git a/launcher/Env.h b/launcher/Env.h index 7d1a8bc9..52427696 100644 --- a/launcher/Env.h +++ b/launcher/Env.h @@ -25,7 +25,7 @@ class Index; class Env { - friend class MultiMC; + friend class Launcher; private: struct Private; Env(); diff --git a/launcher/GuiUtil.cpp b/launcher/GuiUtil.cpp index 302206f5..3dd31c7a 100644 --- a/launcher/GuiUtil.cpp +++ b/launcher/GuiUtil.cpp @@ -8,7 +8,7 @@ #include "net/PasteUpload.h" #include "dialogs/CustomMessageBox.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include #include @@ -16,7 +16,7 @@ QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) { ProgressDialog dialog(parentWidget); - auto APIKeySetting = MMC->settings()->get("PasteEEAPIKey").toString(); + auto APIKeySetting = LAUNCHER->settings()->get("PasteEEAPIKey").toString(); if(APIKeySetting == "multimc") { APIKeySetting = BuildConfig.PASTE_EE_KEY; diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index cb38853b..42b2ae1a 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -822,7 +822,7 @@ Task * InstanceList::wrapInstanceTask(InstanceTask * task) QString InstanceList::getStagedInstancePath() { QString key = QUuid::createUuid().toString(); - QString relPath = FS::PathCombine("_MMC_TEMP/" , key); + QString relPath = FS::PathCombine("_LAUNCHER_TEMP/" , key); QDir rootPath(m_instDir); auto path = FS::PathCombine(m_instDir, relPath); if(!rootPath.mkpath(relPath)) diff --git a/launcher/InstanceProxyModel.cpp b/launcher/InstanceProxyModel.cpp index 5317f60c..0311c239 100644 --- a/launcher/InstanceProxyModel.cpp +++ b/launcher/InstanceProxyModel.cpp @@ -1,5 +1,5 @@ #include "InstanceProxyModel.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -12,7 +12,7 @@ QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const QVariant data = QSortFilterProxyModel::data(index, role); if(role == Qt::DecorationRole) { - return QVariant(MMC->icons()->getIcon(data.toString())); + return QVariant(LAUNCHER->icons()->getIcon(data.toString())); } return data; } @@ -22,7 +22,7 @@ bool InstanceProxyModel::subSortLessThan(const QModelIndex &left, { BaseInstance *pdataLeft = static_cast(left.internalPointer()); BaseInstance *pdataRight = static_cast(right.internalPointer()); - QString sortMode = MMC->settings()->get("InstSortMode").toString(); + QString sortMode = LAUNCHER->settings()->get("InstSortMode").toString(); if (sortMode == "LastLaunch") { return pdataLeft->lastLaunch() > pdataRight->lastLaunch(); diff --git a/launcher/InstanceWindow.cpp b/launcher/InstanceWindow.cpp index 015ffe1c..8f73671b 100644 --- a/launcher/InstanceWindow.cpp +++ b/launcher/InstanceWindow.cpp @@ -14,7 +14,7 @@ */ #include "InstanceWindow.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -35,7 +35,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) { setAttribute(Qt::WA_DeleteOnClose); - auto icon = MMC->icons()->getIcon(m_instance->iconKey()); + auto icon = LAUNCHER->icons()->getIcon(m_instance->iconKey()); QString windowTitle = tr("Console window for ") + m_instance->name(); // Set window properties @@ -87,9 +87,9 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) // restore window state { - auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray(); + auto base64State = LAUNCHER->settings()->get("ConsoleWindowState").toByteArray(); restoreState(QByteArray::fromBase64(base64State)); - auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray(); + auto base64Geometry = LAUNCHER->settings()->get("ConsoleWindowGeometry").toByteArray(); restoreGeometry(QByteArray::fromBase64(base64Geometry)); } @@ -148,7 +148,7 @@ void InstanceWindow::updateLaunchButtons() void InstanceWindow::on_btnLaunchMinecraftOffline_clicked() { - MMC->launch(m_instance, false, nullptr); + LAUNCHER->launch(m_instance, false, nullptr); } void InstanceWindow::on_InstanceLaunchTask_changed(shared_qobject_ptr proc) @@ -183,8 +183,8 @@ void InstanceWindow::closeEvent(QCloseEvent *event) return; } - MMC->settings()->set("ConsoleWindowState", saveState().toBase64()); - MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("ConsoleWindowState", saveState().toBase64()); + LAUNCHER->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); emit isClosing(); event->accept(); } @@ -198,11 +198,11 @@ void InstanceWindow::on_btnKillMinecraft_clicked() { if(m_instance->isRunning()) { - MMC->kill(m_instance); + LAUNCHER->kill(m_instance); } else { - MMC->launch(m_instance, true, nullptr); + LAUNCHER->launch(m_instance, true, nullptr); } } diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 190605fd..15972923 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -1,7 +1,7 @@ #include "LaunchController.h" #include "MainWindow.h" #include -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/ProfileSelectDialog.h" #include "dialogs/ProgressDialog.h" @@ -39,7 +39,7 @@ void LaunchController::login() { JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget); // Find an account to use. - std::shared_ptr accounts = MMC->accounts(); + std::shared_ptr accounts = LAUNCHER->accounts(); if (accounts->count() <= 0) { // Tell the user they need to log in at least one account in order to play. @@ -56,7 +56,7 @@ void LaunchController::login() { if (reply == QMessageBox::Yes) { // Open the account manager. - MMC->ShowGlobalSettings(m_parentWidget, "accounts"); + LAUNCHER->ShowGlobalSettings(m_parentWidget, "accounts"); } } @@ -254,7 +254,7 @@ void LaunchController::launchInstance() auto showConsole = m_instance->settings()->get("ShowConsole").toBool(); if(!console && showConsole) { - MMC->showInstanceWindow(m_instance); + LAUNCHER->showInstanceWindow(m_instance); } connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded); @@ -360,7 +360,7 @@ void LaunchController::onFailed(QString reason) { if(m_instance->settings()->get("ShowConsoleOnError").toBool()) { - MMC->showInstanceWindow(m_instance, "console"); + LAUNCHER->showInstanceWindow(m_instance, "console"); } emitFailed(reason); } diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp new file mode 100644 index 00000000..ab74a324 --- /dev/null +++ b/launcher/Launcher.cpp @@ -0,0 +1,1493 @@ +#include "Launcher.h" +#include "BuildConfig.h" +#include "MainWindow.h" +#include "InstanceWindow.h" + +#include "groupview/AccessibleGroupView.h" +#include + +#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 "setupwizard/SetupWizard.h" +#include "setupwizard/LanguageWizardPage.h" +#include "setupwizard/JavaWizardPage.h" +#include "setupwizard/AnalyticsWizardPage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialogs/CustomMessageBox.h" +#include "InstanceList.h" + +#include +#include "icons/IconList.h" +#include "net/HttpMetaCache.h" +#include "Env.h" + +#include "java/JavaUtils.h" + +#include "updater/UpdateChecker.h" + +#include "tools/JProfiler.h" +#include "tools/JVisualVM.h" +#include "tools/MCEditTool.h" + +#include +#include "settings/INISettingsObject.h" +#include "settings/Setting.h" + +#include "translations/TranslationsModel.h" + +#include +#include +#include +#include + +#include +#include + +#include "pagedialog/PageDialog.h" + + +#if defined Q_OS_WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#endif + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +static const QLatin1String liveCheckFile("live.check"); + +using namespace Commandline; + +#define MACOS_HINT "If you are on macOS Sierra, you might have to move MultiMC.app to your /Applications or ~/Applications folder. "\ + "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ + "\n" + +namespace { +void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + const char *levels = "DWCFIS"; + const QString format("%1 %2 %3\n"); + + qint64 msecstotal = LAUNCHER->timeSinceStart(); + qint64 seconds = msecstotal / 1000; + qint64 msecs = msecstotal % 1000; + QString foo; + char buf[1025] = {0}; + ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs); + + QString out = format.arg(buf).arg(levels[type]).arg(msg); + + LAUNCHER->logFile->write(out.toUtf8()); + LAUNCHER->logFile->flush(); + QTextStream(stderr) << out.toLocal8Bit(); + fflush(stderr); +} + +QString getIdealPlatform(QString currentPlatform) { + auto info = Sys::getKernelInfo(); + switch(info.kernelType) { + case Sys::KernelType::Darwin: { + if(info.kernelMajor >= 17) { + // macOS 10.13 or newer + return "osx64-5.15.2"; + } + else { + // macOS 10.12 or older + return "osx64"; + } + } + case Sys::KernelType::Windows: { + // FIXME: 5.15.2 is not stable on Windows, due to a large number of completely unpredictable and hard to reproduce issues + break; +/* + if(info.kernelMajor == 6 && info.kernelMinor >= 1) { + // Windows 7 + return "win32-5.15.2"; + } + else if (info.kernelMajor > 6) { + // Above Windows 7 + return "win32-5.15.2"; + } + else { + // Below Windows 7 + return "win32"; + } +*/ + } + case Sys::KernelType::Undetermined: + case Sys::KernelType::Linux: { + break; + } + } + return currentPlatform; +} + +} + +Launcher::Launcher(int &argc, char **argv) : QApplication(argc, argv) +{ +#if defined Q_OS_WIN32 + // attach the parent console + if(AttachConsole(ATTACH_PARENT_PROCESS)) + { + // if attach succeeds, reopen and sync all the i/o + if(freopen("CON", "w", stdout)) + { + std::cout.sync_with_stdio(); + } + if(freopen("CON", "w", stderr)) + { + std::cerr.sync_with_stdio(); + } + if(freopen("CON", "r", stdin)) + { + std::cin.sync_with_stdio(); + } + auto out = GetStdHandle (STD_OUTPUT_HANDLE); + DWORD written; + const char * endline = "\n"; + WriteConsole(out, endline, strlen(endline), &written, NULL); + consoleAttached = true; + } +#endif + setOrganizationName("MultiMC"); + setOrganizationDomain("multimc.org"); + setApplicationName("MultiMC5"); + setApplicationDisplayName("MultiMC 5"); + setApplicationVersion(BuildConfig.printableVersionString()); + + startTime = QDateTime::currentDateTime(); + +#ifdef Q_OS_LINUX + { + QFile osrelease("/proc/sys/kernel/osrelease"); + if (osrelease.open(QFile::ReadOnly | QFile::Text)) { + QTextStream in(&osrelease); + auto contents = in.readAll(); + if( + contents.contains("WSL", Qt::CaseInsensitive) || + contents.contains("Microsoft", Qt::CaseInsensitive) + ) { + showFatalErrorMessage( + "Unsupported system detected!", + "Linux-on-Windows distributions are not supported.\n\n" + "Please use the Windows MultiMC binary when playing on Windows." + ); + return; + } + } + } +#endif + + // Don't quit on hiding the last window + this->setQuitOnLastWindowClosed(false); + + // Commandline parsing + QHash args; + { + Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals); + + // --help + parser.addSwitch("help"); + parser.addShortOpt("help", 'h'); + parser.addDocumentation("help", "Display this help and exit."); + // --version + parser.addSwitch("version"); + parser.addShortOpt("version", 'V'); + parser.addDocumentation("version", "Display program version and exit."); + // --dir + parser.addOption("dir"); + parser.addShortOpt("dir", 'd'); + parser.addDocumentation("dir", "Use the supplied folder as MultiMC root instead of " + "the binary location (use '.' for current)"); + // --launch + parser.addOption("launch"); + parser.addShortOpt("launch", 'l'); + parser.addDocumentation("launch", "Launch the specified instance (by instance ID)"); + // --server + parser.addOption("server"); + parser.addShortOpt("server", 's'); + parser.addDocumentation("server", "Join the specified server on launch " + "(only valid in combination with --launch)"); + // --alive + parser.addSwitch("alive"); + parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after MultiMC starts"); + // --import + parser.addOption("import"); + parser.addShortOpt("import", 'I'); + parser.addDocumentation("import", "Import instance from specified zip (local path or URL)"); + + // parse the arguments + try + { + args = parser.parse(arguments()); + } + catch (const ParsingError &e) + { + std::cerr << "CommandLineError: " << e.what() << std::endl; + if(argc > 0) + std::cerr << "Try '" << argv[0] << " -h' to get help on MultiMC's command line parameters." + << std::endl; + m_status = Launcher::Failed; + return; + } + + // display help and exit + if (args["help"].toBool()) + { + std::cout << qPrintable(parser.compileHelp(arguments()[0])); + m_status = Launcher::Succeeded; + return; + } + + // display version and exit + if (args["version"].toBool()) + { + std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; + std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; + m_status = Launcher::Succeeded; + return; + } + } + m_instanceIdToLaunch = args["launch"].toString(); + m_serverToJoin = args["server"].toString(); + m_liveCheck = args["alive"].toBool(); + m_zipToImport = args["import"].toUrl(); + + QString origcwdPath = QDir::currentPath(); + QString binPath = applicationDirPath(); + QString adjustedBy; + QString dataPath; + // change folder + QString dirParam = args["dir"].toString(); + if (!dirParam.isEmpty()) + { + // the dir param. it makes multimc data path point to whatever the user specified + // on command line + adjustedBy += "Command line " + dirParam; + dataPath = dirParam; + } + else + { +#ifdef MULTIMC_LINUX_DATADIR + QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); + if (xdgDataHome.isEmpty()) + xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); + dataPath = xdgDataHome + "/multimc"; + adjustedBy += "XDG standard " + dataPath; +#elif defined(Q_OS_MAC) + QDir foo(FS::PathCombine(applicationDirPath(), "../../Data")); + dataPath = foo.absolutePath(); + adjustedBy += "Fallback to special Mac location " + dataPath; +#else + dataPath = applicationDirPath(); + adjustedBy += "Fallback to binary path " + dataPath; +#endif + } + + if (!FS::ensureFolderPathExists(dataPath)) + { + showFatalErrorMessage( + "MultiMC data folder could not be created.", + "MultiMC data folder could not be created.\n" + "\n" +#if defined(Q_OS_MAC) + MACOS_HINT +#endif + "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n" + "\n" + "MultiMC cannot continue until you fix this problem." + ); + return; + } + if (!QDir::setCurrent(dataPath)) + { + showFatalErrorMessage( + "MultiMC data folder could not be opened.", + "MultiMC data folder could not be opened.\n" + "\n" +#if defined(Q_OS_MAC) + MACOS_HINT +#endif + "Make sure you have the right permissions to the MultiMC data folder.\n" + "\n" + "MultiMC cannot continue until you fix this problem." + ); + return; + } + + if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) + { + std::cerr << "--server can only be used in combination with --launch!" << std::endl; + m_status = Launcher::Failed; + return; + } + +#if defined(Q_OS_MAC) + // move user data to new location if on macOS and it still exists in Contents/MacOS + QDir fi(applicationDirPath()); + QString originalData = fi.absolutePath(); + // if the config file exists in Contents/MacOS, then user data is still there and needs to moved + if (QFileInfo::exists(FS::PathCombine(originalData, "multimc.cfg"))) + { + if (!QFileInfo::exists(FS::PathCombine(originalData, "dontmovemacdata"))) + { + QMessageBox::StandardButton askMoveDialogue; + askMoveDialogue = QMessageBox::question(nullptr, "MultiMC 5", "Would you like to move application data to a new data location? It will improve MultiMC's performance, but if you switch to older versions it will look like instances have disappeared. If you select no, you can migrate later in settings. You should select yes unless you're commonly switching between different versions of MultiMC (eg. develop and stable).", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + if (askMoveDialogue == QMessageBox::Yes) + { + qDebug() << "On macOS and found config file in old location, moving user data..."; + QDir dir; + QStringList dataFiles { + "*.log", // MultiMC-@.log + "accounts.json", + "accounts", + "assets", + "cache", + "icons", + "instances", + "libraries", + "meta", + "metacache", + "mods", + "multimc.cfg", + "themes", + "translations" + }; + QDirIterator files(originalData, dataFiles); + while (files.hasNext()) { + QString filePath(files.next()); + QString fileName(files.fileName()); + if (!dir.rename(filePath, FS::PathCombine(dataPath, fileName))) + { + qWarning() << "Failed to move " << fileName; + } + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + QFile file(originalData + "/dontmovemacdata"); + file.open(QIODevice::WriteOnly); + } + } + else + { + dataPath = originalData; + QDir::setCurrent(dataPath); + } + } +#endif + + /* + * Establish the mechanism for communication with an already running MultiMC that uses the same data path. + * If there is one, tell it what the user actually wanted to do and exit. + * We want to initialize this before logging to avoid messing with the log of a potential already running copy. + */ + auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString()); + { + // 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); + if(m_peerInstance->isClient()) + { + int timeout = 2000; + + if(m_instanceIdToLaunch.isEmpty()) + { + m_peerInstance->sendMessage("activate", timeout); + + if(!m_zipToImport.isEmpty()) + { + m_peerInstance->sendMessage("import " + m_zipToImport.toString(), timeout); + } + } + else + { + if(!m_serverToJoin.isEmpty()) + { + m_peerInstance->sendMessage( + "launch-with-server " + m_instanceIdToLaunch + " " + m_serverToJoin, timeout); + } + else + { + m_peerInstance->sendMessage("launch " + m_instanceIdToLaunch, timeout); + } + } + m_status = Launcher::Succeeded; + return; + } + } + + // init the logger + { + static const QString logBase = "MultiMC-%0.log"; + auto moveFile = [](const QString &oldName, const QString &newName) + { + QFile::remove(newName); + QFile::copy(oldName, newName); + QFile::remove(oldName); + }; + + moveFile(logBase.arg(3), logBase.arg(4)); + moveFile(logBase.arg(2), logBase.arg(3)); + moveFile(logBase.arg(1), logBase.arg(2)); + moveFile(logBase.arg(0), logBase.arg(1)); + + logFile = std::unique_ptr(new QFile(logBase.arg(0))); + if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + showFatalErrorMessage( + "MultiMC data folder is not writable!", + "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n" + "\n" + #if defined(Q_OS_MAC) + MACOS_HINT + #endif + "Make sure you have write permissions to the MultiMC data folder.\n" + "\n" + "MultiMC cannot continue until you fix this problem." + ); + return; + } + qInstallMessageHandler(appDebugOutput); + qDebug() << "<> Log initialized."; + } + + // Set up paths + { + // Root path is used for updates. +#ifdef Q_OS_LINUX + QDir foo(FS::PathCombine(binPath, "..")); + m_rootPath = foo.absolutePath(); +#elif defined(Q_OS_WIN32) + m_rootPath = binPath; +#elif defined(Q_OS_MAC) + QDir foo(FS::PathCombine(binPath, "../..")); + m_rootPath = foo.absolutePath(); + // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) + FS::updateTimestamp(m_rootPath); +#endif + +#ifdef MULTIMC_JARS_LOCATION + ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); +#endif + + qDebug() << "MultiMC 5, (c) 2013-2021 MultiMC Contributors"; + qDebug() << "Version : " << BuildConfig.printableVersionString(); + qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; + qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; + if (adjustedBy.size()) + { + qDebug() << "Work dir before adjustment : " << origcwdPath; + qDebug() << "Work dir after adjustment : " << QDir::currentPath(); + qDebug() << "Adjusted by : " << adjustedBy; + } + else + { + qDebug() << "Work dir : " << QDir::currentPath(); + } + qDebug() << "Binary path : " << binPath; + qDebug() << "Application root path : " << m_rootPath; + if(!m_instanceIdToLaunch.isEmpty()) + { + qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; + } + if(!m_serverToJoin.isEmpty()) + { + qDebug() << "Address of server to join :" << m_serverToJoin; + } + qDebug() << "<> Paths set."; + } + + do // once + { + if(m_liveCheck) + { + QFile check(liveCheckFile); + if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qWarning() << "Could not open" << liveCheckFile << "for writing!"; + break; + } + auto payload = appID.toString().toUtf8(); + if(check.write(payload) != payload.size()) + { + qWarning() << "Could not write into" << liveCheckFile << "!"; + check.remove(); + break; + } + check.close(); + } + } while(false); + + // Initialize application settings + { + m_settings.reset(new INISettingsObject("multimc.cfg", this)); + // Updates + m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL); + m_settings->registerSetting("AutoUpdate", true); + + // Theming + m_settings->registerSetting("IconTheme", QString("multimc")); + m_settings->registerSetting("ApplicationTheme", QString("system")); + + // Notifications + m_settings->registerSetting("ShownNotifications", QString()); + + // Remembered state + m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); + + QString defaultMonospace; + int defaultSize = 11; +#ifdef Q_OS_WIN32 + defaultMonospace = "Courier"; + defaultSize = 10; +#elif defined(Q_OS_MAC) + defaultMonospace = "Menlo"; +#else + defaultMonospace = "Monospace"; +#endif + + // resolve the font so the default actually matches + QFont consoleFont; + consoleFont.setFamily(defaultMonospace); + consoleFont.setStyleHint(QFont::Monospace); + consoleFont.setFixedPitch(true); + QFontInfo consoleFontInfo(consoleFont); + QString resolvedDefaultMonospace = consoleFontInfo.family(); + QFont resolvedFont(resolvedDefaultMonospace); + qDebug() << "Detected default console font:" << resolvedDefaultMonospace + << ", substitutions:" << resolvedFont.substitutions().join(','); + + m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace); + m_settings->registerSetting("ConsoleFontSize", defaultSize); + m_settings->registerSetting("ConsoleMaxLines", 100000); + m_settings->registerSetting("ConsoleOverflowStop", true); + + // Folders + m_settings->registerSetting("InstanceDir", "instances"); + m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods"); + m_settings->registerSetting("IconsDir", "icons"); + + // Editors + m_settings->registerSetting("JsonEditor", QString()); + + // Language + m_settings->registerSetting("Language", QString()); + + // Console + m_settings->registerSetting("ShowConsole", false); + m_settings->registerSetting("AutoCloseConsole", false); + m_settings->registerSetting("ShowConsoleOnError", true); + m_settings->registerSetting("LogPrePostOutput", true); + + // Window Size + m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false); + m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854); + m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480); + + // Proxy Settings + m_settings->registerSetting("ProxyType", "None"); + m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1"); + m_settings->registerSetting("ProxyPort", 8080); + m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, ""); + m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, ""); + + // Memory + m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); + m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024); + m_settings->registerSetting("PermGen", 128); + + // Java Settings + m_settings->registerSetting("JavaPath", ""); + m_settings->registerSetting("JavaTimestamp", 0); + m_settings->registerSetting("JavaArchitecture", ""); + m_settings->registerSetting("JavaVersion", ""); + m_settings->registerSetting("JavaVendor", ""); + m_settings->registerSetting("LastHostname", ""); + m_settings->registerSetting("JvmArgs", ""); + + // Native library workarounds + m_settings->registerSetting("UseNativeOpenAL", false); + m_settings->registerSetting("UseNativeGLFW", false); + + // Game time + m_settings->registerSetting("ShowGameTime", true); + m_settings->registerSetting("RecordGameTime", true); + + // Minecraft launch method + m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); + + // Wrapper command for launch + m_settings->registerSetting("WrapperCommand", ""); + + // Custom Commands + m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); + m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); + + // The cat + m_settings->registerSetting("TheCat", false); + + m_settings->registerSetting("InstSortMode", "Name"); + m_settings->registerSetting("SelectedInstance", QString()); + + // Window state and geometry + m_settings->registerSetting("MainWindowState", ""); + m_settings->registerSetting("MainWindowGeometry", ""); + + m_settings->registerSetting("ConsoleWindowState", ""); + m_settings->registerSetting("ConsoleWindowGeometry", ""); + + m_settings->registerSetting("SettingsGeometry", ""); + + m_settings->registerSetting("PagedGeometry", ""); + + m_settings->registerSetting("NewInstanceGeometry", ""); + + m_settings->registerSetting("UpdateDialogGeometry", ""); + + // paste.ee API key + m_settings->registerSetting("PasteEEAPIKey", "multimc"); + + if(!BuildConfig.ANALYTICS_ID.isEmpty()) + { + // Analytics + m_settings->registerSetting("Analytics", true); + m_settings->registerSetting("AnalyticsSeen", 0); + m_settings->registerSetting("AnalyticsClientID", QString()); + } + + // Init page provider + { + m_globalSettingsProvider = std::make_shared(tr("Settings")); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + } + qDebug() << "<> Settings loaded."; + } + +#ifndef QT_NO_ACCESSIBILITY + QAccessible::installFactory(groupViewAccessibleFactory); +#endif /* !QT_NO_ACCESSIBILITY */ + + // load translations + { + m_translations.reset(new TranslationsModel("translations")); + auto bcp47Name = m_settings->get("Language").toString(); + m_translations->selectLanguage(bcp47Name); + qDebug() << "Your language is" << bcp47Name; + qDebug() << "<> Translations loaded."; + } + + // initialize the updater + if(BuildConfig.UPDATER_ENABLED) + { + 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)); + qDebug() << "<> Updater started."; + } + + // Instance icons + { + auto setting = LAUNCHER->settings()->getSetting("IconsDir"); + QStringList instFolders = + { + ":/icons/multimc/32x32/instances/", + ":/icons/multimc/50x50/instances/", + ":/icons/multimc/128x128/instances/", + ":/icons/multimc/scalable/instances/" + }; + m_icons.reset(new IconList(instFolders, setting->get().toString())); + connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) + { + m_icons->directoryChanged(value.toString()); + }); + ENV.registerIconList(m_icons); + qDebug() << "<> Instance icons intialized."; + } + + // Icon themes + { + // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! + // set icon theme search path! + auto searchPaths = QIcon::themeSearchPaths(); + searchPaths.append("iconthemes"); + QIcon::setThemeSearchPaths(searchPaths); + qDebug() << "<> Icon themes initialized."; + } + + // Initialize widget themes + { + auto insertTheme = [this](ITheme * theme) + { + m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); + }; + auto darkTheme = new DarkTheme(); + insertTheme(new SystemTheme()); + insertTheme(darkTheme); + insertTheme(new BrightTheme()); + insertTheme(new CustomTheme(darkTheme, "custom")); + qDebug() << "<> Widget themes initialized."; + } + + // initialize and load all instances + { + auto InstDirSetting = m_settings->getSetting("InstanceDir"); + // instance path: check for problems with '!' in instance path and warn the user in the log + // and remember that we have to show him a dialog when the gui starts (if it does so) + QString instDir = InstDirSetting->get().toString(); + qDebug() << "Instance path : " << instDir; + if (FS::checkProblemticPathJava(QDir(instDir))) + { + qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; + } + m_instances.reset(new InstanceList(m_settings, instDir, this)); + connect(InstDirSetting.get(), &Setting::SettingChanged, m_instances.get(), &InstanceList::on_InstFolderChanged); + qDebug() << "Loading Instances..."; + m_instances->loadList(); + qDebug() << "<> Instances loaded."; + } + + // and accounts + { + m_accounts.reset(new AccountList(this)); + qDebug() << "Loading accounts..."; + m_accounts->setListFilePath("accounts.json", true); + m_accounts->loadList(); + qDebug() << "<> Accounts loaded."; + } + + // init the http meta cache + { + ENV.initHttpMetaCache(); + qDebug() << "<> Cache initialized."; + } + + // init proxy settings + { + QString proxyTypeStr = settings()->get("ProxyType").toString(); + QString addr = settings()->get("ProxyAddr").toString(); + int port = settings()->get("ProxyPort").value(); + 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(); + + //FIXME: what to do with these? + m_profilers.insert("jprofiler", std::shared_ptr(new JProfilerFactory())); + m_profilers.insert("jvisualvm", std::shared_ptr(new JVisualVMFactory())); + for (auto profiler : m_profilers.values()) + { + profiler->registerSettings(m_settings); + } + + // Create the MCEdit thing... why is this here? + { + m_mcedit.reset(new MCEditTool(m_settings)); + } + + connect(this, &Launcher::aboutToQuit, [this](){ + if(m_instances) + { + // save any remaining instance state + m_instances->saveNow(); + } + if(logFile) + { + logFile->flush(); + logFile->close(); + } + }); + + { + setIconTheme(settings()->get("IconTheme").toString()); + qDebug() << "<> Icon theme set."; + setApplicationTheme(settings()->get("ApplicationTheme").toString(), true); + qDebug() << "<> Application theme set."; + } + + // Initialize analytics + [this]() + { + const int analyticsVersion = 2; + if(BuildConfig.ANALYTICS_ID.isEmpty()) + { + return; + } + + auto analyticsSetting = m_settings->getSetting("Analytics"); + connect(analyticsSetting.get(), &Setting::SettingChanged, this, &Launcher::analyticsSettingChanged); + QString clientID = m_settings->get("AnalyticsClientID").toString(); + if(clientID.isEmpty()) + { + clientID = QUuid::createUuid().toString(); + clientID.remove(QLatin1Char('{')); + clientID.remove(QLatin1Char('}')); + m_settings->set("AnalyticsClientID", clientID); + } + m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this); + m_analytics->setLogLevel(GAnalytics::Debug); + m_analytics->setAnonymizeIPs(true); + m_analytics->setNetworkAccessManager(&ENV.qnam()); + + if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version()) + { + qDebug() << "Analytics info not seen by user yet (or old version)."; + return; + } + if(!m_settings->get("Analytics").toBool()) + { + qDebug() << "Analytics disabled by user."; + return; + } + + m_analytics->enable(); + qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID; + }(); + + if(createSetupWizard()) + { + return; + } + performMainStartupAction(); +} + +bool Launcher::createSetupWizard() +{ + bool javaRequired = [&]() + { + QString currentHostName = QHostInfo::localHostName(); + QString oldHostName = settings()->get("LastHostname").toString(); + if (currentHostName != oldHostName) + { + settings()->set("LastHostname", currentHostName); + return true; + } + QString currentJavaPath = settings()->get("JavaPath").toString(); + QString actualPath = FS::ResolveExecutable(currentJavaPath); + if (actualPath.isNull()) + { + return true; + } + return false; + }(); + bool analyticsRequired = [&]() + { + if(BuildConfig.ANALYTICS_ID.isEmpty()) + { + return false; + } + if (!settings()->get("Analytics").toBool()) + { + return false; + } + if (settings()->get("AnalyticsSeen").toInt() < analytics()->version()) + { + return true; + } + return false; + }(); + bool languageRequired = [&]() + { + if (settings()->get("Language").toString().isEmpty()) + return true; + return false; + }(); + bool wizardRequired = javaRequired || analyticsRequired || languageRequired; + + if(wizardRequired) + { + m_setupWizard = new SetupWizard(nullptr); + if (languageRequired) + { + m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); + } + if (javaRequired) + { + m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); + } + if(analyticsRequired) + { + m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard)); + } + connect(m_setupWizard, &QDialog::finished, this, &Launcher::setupWizardFinished); + m_setupWizard->show(); + return true; + } + return false; +} + +void Launcher::setupWizardFinished(int status) +{ + qDebug() << "Wizard result =" << status; + performMainStartupAction(); +} + +void Launcher::performMainStartupAction() +{ + m_status = Launcher::Initialized; + if(!m_instanceIdToLaunch.isEmpty()) + { + auto inst = instances()->getInstanceById(m_instanceIdToLaunch); + if(inst) + { + MinecraftServerTargetPtr serverToJoin = nullptr; + + if(!m_serverToJoin.isEmpty()) + { + serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); + qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching with server" << m_serverToJoin; + } + else + { + qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; + } + + launch(inst, true, nullptr, serverToJoin); + return; + } + } + if(!m_mainWindow) + { + // normal main window + showMainWindow(false); + qDebug() << "<> Main window shown."; + } + if(!m_zipToImport.isEmpty()) + { + qDebug() << "<> Importing instance from zip:" << m_zipToImport; + m_mainWindow->droppedURLs({ m_zipToImport }); + } +} + +void Launcher::showFatalErrorMessage(const QString& title, const QString& content) +{ + m_status = Launcher::Failed; + auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); + dialog->exec(); +} + +Launcher::~Launcher() +{ + // kill the other globals. + Env::dispose(); + + // Shut down logger by setting the logger function to nothing + qInstallMessageHandler(nullptr); + +#if defined Q_OS_WIN32 + // Detach from Windows console + if(consoleAttached) + { + fclose(stdout); + fclose(stdin); + fclose(stderr); + FreeConsole(); + } +#endif +} + +void Launcher::messageReceived(const QString& message) +{ + if(status() != Initialized) + { + qDebug() << "Received message" << message << "while still initializing. It will be ignored."; + return; + } + + QString command = message.section(' ', 0, 0); + + if(command == "activate") + { + showMainWindow(); + } + else if(command == "import") + { + QString arg = message.section(' ', 1); + if(arg.isEmpty()) + { + qWarning() << "Received" << command << "message without a zip path/URL."; + return; + } + m_mainWindow->droppedURLs({ QUrl(arg) }); + } + else if(command == "launch") + { + QString arg = message.section(' ', 1); + if(arg.isEmpty()) + { + qWarning() << "Received" << command << "message without an instance ID."; + return; + } + auto inst = instances()->getInstanceById(arg); + if(inst) + { + launch(inst, true, nullptr); + } + } + else if(command == "launch-with-server") + { + QString instanceID = message.section(' ', 1, 1); + QString serverToJoin = message.section(' ', 2, 2); + if(instanceID.isEmpty()) + { + qWarning() << "Received" << command << "message without an instance ID."; + return; + } + if(serverToJoin.isEmpty()) + { + qWarning() << "Received" << command << "message without a server to join."; + return; + } + auto inst = instances()->getInstanceById(instanceID); + if(inst) + { + launch( + inst, + true, + nullptr, + std::make_shared(MinecraftServerTarget::parse(serverToJoin)) + ); + } + } + else + { + qWarning() << "Received invalid message" << message; + } +} + +void Launcher::analyticsSettingChanged(const Setting&, QVariant value) +{ + if(!m_analytics) + return; + bool enabled = value.toBool(); + if(enabled) + { + qDebug() << "Analytics enabled by user."; + } + else + { + qDebug() << "Analytics disabled by user."; + } + m_analytics->enable(enabled); +} + +std::shared_ptr Launcher::translations() +{ + return m_translations; +} + +std::shared_ptr Launcher::javalist() +{ + if (!m_javalist) + { + m_javalist.reset(new JavaInstallList()); + } + return m_javalist; +} + +std::vector Launcher::getValidApplicationThemes() +{ + std::vector ret; + auto iter = m_themes.cbegin(); + while (iter != m_themes.cend()) + { + ret.push_back((*iter).second.get()); + iter++; + } + return ret; +} + +void Launcher::setApplicationTheme(const QString& name, bool initial) +{ + auto systemPalette = qApp->palette(); + auto themeIter = m_themes.find(name); + if(themeIter != m_themes.end()) + { + auto & theme = (*themeIter).second; + theme->apply(initial); + } + else + { + qWarning() << "Tried to set invalid theme:" << name; + } +} + +void Launcher::setIconTheme(const QString& name) +{ + XdgIcon::setThemeName(name); +} + +QIcon Launcher::getThemedIcon(const QString& name) +{ + return XdgIcon::fromTheme(name); +} + +bool Launcher::openJsonEditor(const QString &filename) +{ + const QString file = QDir::current().absoluteFilePath(filename); + if (m_settings->get("JsonEditor").toString().isEmpty()) + { + return DesktopServices::openUrl(QUrl::fromLocalFile(file)); + } + else + { + //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); + return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file}); + } +} + +bool Launcher::launch( + InstancePtr instance, + bool online, + BaseProfilerFactory *profiler, + MinecraftServerTargetPtr serverToJoin +) { + if(m_updateRunning) + { + qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; + } + else if(instance->canLaunch()) + { + auto & extras = m_instanceExtras[instance->id()]; + auto & window = extras.window; + if(window) + { + if(!window->saveAll()) + { + return false; + } + } + auto & controller = extras.controller; + controller.reset(new LaunchController()); + controller->setInstance(instance); + controller->setOnline(online); + controller->setProfiler(profiler); + controller->setServerToJoin(serverToJoin); + if(window) + { + controller->setParentWidget(window); + } + else if(m_mainWindow) + { + controller->setParentWidget(m_mainWindow); + } + connect(controller.get(), &LaunchController::succeeded, this, &Launcher::controllerSucceeded); + connect(controller.get(), &LaunchController::failed, this, &Launcher::controllerFailed); + addRunningInstance(); + controller->start(); + return true; + } + else if (instance->isRunning()) + { + showInstanceWindow(instance, "console"); + return true; + } + else if (instance->canEdit()) + { + showInstanceWindow(instance); + return true; + } + return false; +} + +bool Launcher::kill(InstancePtr instance) +{ + if (!instance->isRunning()) + { + qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; + return false; + } + auto & extras = m_instanceExtras[instance->id()]; + // NOTE: copy of the shared pointer keeps it alive + auto controller = extras.controller; + if(controller) + { + return controller->abort(); + } + return true; +} + +void Launcher::addRunningInstance() +{ + m_runningInstances ++; + if(m_runningInstances == 1) + { + emit updateAllowedChanged(false); + } +} + +void Launcher::subRunningInstance() +{ + if(m_runningInstances == 0) + { + qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; + return; + } + m_runningInstances --; + if(m_runningInstances == 0) + { + emit updateAllowedChanged(true); + } +} + +bool Launcher::shouldExitNow() const +{ + return m_runningInstances == 0 && m_openWindows == 0; +} + +bool Launcher::updatesAreAllowed() +{ + return m_runningInstances == 0; +} + +void Launcher::updateIsRunning(bool running) +{ + m_updateRunning = running; +} + + +void Launcher::controllerSucceeded() +{ + auto controller = qobject_cast(QObject::sender()); + if(!controller) + return; + auto id = controller->id(); + auto & extras = m_instanceExtras[id]; + + // on success, do... + if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) + { + if(extras.window) + { + extras.window->close(); + } + } + extras.controller.reset(); + subRunningInstance(); + + // quit when there are no more windows. + if(shouldExitNow()) + { + m_status = Status::Succeeded; + exit(0); + } +} + +void Launcher::controllerFailed(const QString& error) +{ + Q_UNUSED(error); + auto controller = qobject_cast(QObject::sender()); + if(!controller) + return; + auto id = controller->id(); + auto & extras = m_instanceExtras[id]; + + // on failure, do... nothing + extras.controller.reset(); + subRunningInstance(); + + // quit when there are no more windows. + if(shouldExitNow()) + { + m_status = Status::Failed; + exit(1); + } +} + +void Launcher::ShowGlobalSettings(class QWidget* parent, QString open_page) +{ + if(!m_globalSettingsProvider) { + return; + } + emit globalSettingsAboutToOpen(); + { + SettingsObject::Lock lock(LAUNCHER->settings()); + PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); + dlg.exec(); + } + emit globalSettingsClosed(); +} + +MainWindow* Launcher::showMainWindow(bool minimized) +{ + if(m_mainWindow) + { + m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); + m_mainWindow->raise(); + m_mainWindow->activateWindow(); + } + 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())); + if(minimized) + { + m_mainWindow->showMinimized(); + } + else + { + m_mainWindow->show(); + } + + m_mainWindow->checkInstancePathForProblems(); + connect(this, &Launcher::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); + connect(m_mainWindow, &MainWindow::isClosing, this, &Launcher::on_windowClose); + m_openWindows++; + } + // FIXME: move this somewhere else... + if(m_analytics) + { + auto windowSize = m_mainWindow->size(); + auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height()); + qDebug() << "Viewport size" << sizeString; + m_analytics->setViewportSize(sizeString); + /* + * cm1 = java min heap [MB] + * cm2 = java max heap [MB] + * cm3 = system RAM [MB] + * + * cd1 = java version + * cd2 = java architecture + * cd3 = system architecture + * cd4 = CPU architecture + */ + QVariantMap customValues; + int min = m_settings->get("MinMemAlloc").toInt(); + int max = m_settings->get("MaxMemAlloc").toInt(); + if(min < max) + { + customValues["cm1"] = min; + customValues["cm2"] = max; + } + else + { + customValues["cm1"] = max; + customValues["cm2"] = min; + } + + constexpr uint64_t Mega = 1024ull * 1024ull; + int ramSize = int(Sys::getSystemRam() / Mega); + qDebug() << "RAM size is" << ramSize << "MB"; + customValues["cm3"] = ramSize; + + customValues["cd1"] = m_settings->get("JavaVersion"); + customValues["cd2"] = m_settings->get("JavaArchitecture"); + customValues["cd3"] = Sys::isSystem64bit() ? "64":"32"; + customValues["cd4"] = Sys::isCPU64bit() ? "64":"32"; + auto kernelInfo = Sys::getKernelInfo(); + customValues["cd5"] = kernelInfo.kernelName; + customValues["cd6"] = kernelInfo.kernelVersion; + auto distInfo = Sys::getDistributionInfo(); + if(!distInfo.distributionName.isEmpty()) + { + customValues["cd7"] = distInfo.distributionName; + } + if(!distInfo.distributionVersion.isEmpty()) + { + customValues["cd8"] = distInfo.distributionVersion; + } + m_analytics->sendScreenView("Main Window", customValues); + } + return m_mainWindow; +} + +InstanceWindow *Launcher::showInstanceWindow(InstancePtr instance, QString page) +{ + if(!instance) + return nullptr; + auto id = instance->id(); + auto & extras = m_instanceExtras[id]; + auto & window = extras.window; + + if(window) + { + window->raise(); + window->activateWindow(); + } + else + { + window = new InstanceWindow(instance); + m_openWindows ++; + connect(window, &InstanceWindow::isClosing, this, &Launcher::on_windowClose); + } + if(!page.isEmpty()) + { + window->selectPage(page); + } + if(extras.controller) + { + extras.controller->setParentWidget(window); + } + return window; +} + +void Launcher::on_windowClose() +{ + m_openWindows--; + auto instWindow = qobject_cast(QObject::sender()); + if(instWindow) + { + auto & extras = m_instanceExtras[instWindow->instanceId()]; + extras.window = nullptr; + if(extras.controller) + { + extras.controller->setParentWidget(m_mainWindow); + } + } + auto mainWindow = qobject_cast(QObject::sender()); + if(mainWindow) + { + m_mainWindow = nullptr; + } + // quit when there are no more windows. + if(shouldExitNow()) + { + exit(0); + } +} diff --git a/launcher/Launcher.h b/launcher/Launcher.h new file mode 100644 index 00000000..468f8a68 --- /dev/null +++ b/launcher/Launcher.h @@ -0,0 +1,235 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "minecraft/launch/MinecraftServerTarget.h" + +class LaunchController; +class LocalPeer; +class InstanceWindow; +class MainWindow; +class SetupWizard; +class FolderInstanceProvider; +class GenericPageProvider; +class QFile; +class HttpMetaCache; +class SettingsObject; +class InstanceList; +class AccountList; +class IconList; +class QNetworkAccessManager; +class JavaInstallList; +class UpdateChecker; +class BaseProfilerFactory; +class BaseDetachedToolFactory; +class TranslationsModel; +class ITheme; +class MCEditTool; +class GAnalytics; + +#if defined(LAUNCHER) +#undef LAUNCHER +#endif +#define LAUNCHER (static_cast(QCoreApplication::instance())) + +class Launcher : public QApplication +{ + // friends for the purpose of limiting access to deprecated stuff + Q_OBJECT +public: + enum Status + { + StartingUp, + Failed, + Succeeded, + Initialized + }; + +public: + Launcher(int &argc, char **argv); + virtual ~Launcher(); + + GAnalytics *analytics() const + { + return m_analytics; + } + + std::shared_ptr settings() const + { + return m_settings; + } + + qint64 timeSinceStart() const + { + return startTime.msecsTo(QDateTime::currentDateTime()); + } + + QIcon getThemedIcon(const QString& name); + + void setIconTheme(const QString& name); + + std::vector getValidApplicationThemes(); + + void setApplicationTheme(const QString& name, bool initial); + + // DownloadUpdateTask + std::shared_ptr updateChecker() + { + return m_updateChecker; + } + + std::shared_ptr translations(); + + std::shared_ptr javalist(); + + std::shared_ptr instances() const + { + return m_instances; + } + + FolderInstanceProvider * folderProvider() const + { + return m_instanceFolder; + } + + std::shared_ptr icons() const + { + return m_icons; + } + + MCEditTool *mcedit() const + { + return m_mcedit.get(); + } + + std::shared_ptr accounts() const + { + return m_accounts; + } + + Status status() const + { + return m_status; + } + + const QMap> &profilers() const + { + return m_profilers; + } + + /// this is the root of the 'installation'. Used for automatic updates + const QString &root() + { + return m_rootPath; + } + + /*! + * Opens a json file using either a system default editor, or, if not empty, the editor + * specified in the settings + */ + bool openJsonEditor(const QString &filename); + + InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); + MainWindow *showMainWindow(bool minimized = false); + + void updateIsRunning(bool running); + bool updatesAreAllowed(); + + void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); + +signals: + void updateAllowedChanged(bool status); + void globalSettingsAboutToOpen(); + void globalSettingsClosed(); + +public slots: + bool launch( + InstancePtr instance, + bool online = true, + BaseProfilerFactory *profiler = nullptr, + MinecraftServerTargetPtr serverToJoin = nullptr + ); + bool kill(InstancePtr instance); + +private slots: + void on_windowClose(); + void messageReceived(const QString & message); + void controllerSucceeded(); + void controllerFailed(const QString & error); + void analyticsSettingChanged(const Setting &setting, QVariant value); + void setupWizardFinished(int status); + +private: + bool createSetupWizard(); + void performMainStartupAction(); + + // sets the fatal error message and m_status to Failed. + void showFatalErrorMessage(const QString & title, const QString & content); + +private: + void addRunningInstance(); + void subRunningInstance(); + bool shouldExitNow() const; + +private: + QDateTime startTime; + + std::shared_ptr m_settings; + std::shared_ptr m_instances; + FolderInstanceProvider * m_instanceFolder = nullptr; + std::shared_ptr m_icons; + std::shared_ptr m_updateChecker; + std::shared_ptr m_accounts; + std::shared_ptr m_javalist; + std::shared_ptr m_translations; + std::shared_ptr m_globalSettingsProvider; + std::map> m_themes; + std::unique_ptr m_mcedit; + + QMap> m_profilers; + + QString m_rootPath; + Status m_status = Launcher::StartingUp; + +#if defined Q_OS_WIN32 + // used on Windows to attach the standard IO streams + bool consoleAttached = false; +#endif + + // FIXME: attach to instances instead. + struct InstanceXtras + { + InstanceWindow * window = nullptr; + shared_qobject_ptr controller; + }; + std::map m_instanceExtras; + + // main state variables + size_t m_openWindows = 0; + size_t m_runningInstances = 0; + bool m_updateRunning = false; + + // main window, if any + MainWindow * m_mainWindow = nullptr; + + // peer MultiMC instance connector - used to implement single instance MultiMC and signalling + LocalPeer * m_peerInstance = nullptr; + + GAnalytics * m_analytics = nullptr; + SetupWizard * m_setupWizard = nullptr; +public: + QString m_instanceIdToLaunch; + QString m_serverToJoin; + bool m_liveCheck = false; + QUrl m_zipToImport; + std::unique_ptr logFile; +}; diff --git a/launcher/Launcher.in b/launcher/Launcher.in new file mode 100755 index 00000000..b79b276b --- /dev/null +++ b/launcher/Launcher.in @@ -0,0 +1,94 @@ +#!/bin/bash +# Basic start script for running the launcher with the libs packaged with it. + +function printerror { + printf "$1" + if which zenity >/dev/null; then zenity --error --text="$1" &>/dev/null; + elif which kdialog >/dev/null; then kdialog --error "$1" &>/dev/null; + fi +} + +if [[ $EUID -eq 0 ]]; then + printerror "This program should not be run using sudo or as the root user!\n" + exit 1 +fi + + +LAUNCHER_NAME=@Launcher_Name@ +LAUNCHER_DIR="$(dirname "$(readlink -f "$0")")" +echo "Launcher Dir: ${LAUNCHER_DIR}" + +# Set up env - filter out input LD_ variables but pass them in under different names +export GAME_LIBRARY_PATH=${GAME_LIBRARY_PATH-${LD_LIBRARY_PATH}} +export GAME_PRELOAD=${GAME_PRELOAD-${LD_PRELOAD}} +export LD_LIBRARY_PATH="${LAUNCHER_DIR}/bin":$LAUNCHER_LIBRARY_PATH +export LD_PRELOAD=$LAUNCHER_PRELOAD +export QT_PLUGIN_PATH="${LAUNCHER_DIR}/plugins" +export QT_FONTPATH="${LAUNCHER_DIR}/fonts" + +# Detect missing dependencies... +DEPS_LIST=`ldd "${LAUNCHER_DIR}"/plugins/*/*.so 2>/dev/null | grep "not found" | sort -u | awk -vORS=", " '{ print $1 }'` +if [ "x$DEPS_LIST" = "x" ]; then + # We have all our dependencies. Run the launcher. + echo "No missing dependencies found." + + # Just to be sure... + chmod +x "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" + + # Run the launcher + exec -a "${LAUNCHER_DIR}/${LAUNCHER_NAME}" "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@" + + # Run the launcher in valgrind + # valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@" + + # Run the launcher with callgrind, delay instrumentation + # valgrind --log-file="valgrind.log" --tool=callgrind --instr-atstart=no "${LAUNCHER_DIR}/bin/${LAUNCHER_NAME}" -d "${LAUNCHER_DIR}" "$@" + # use callgrind_control -i on/off to profile actions + + # Exit with launcher's exit code. + # exit $? +else + # apt + if which apt-file &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do apt-file -l search $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo apt-get install $COMMAND_LIBS" + # pacman + elif which pkgfile &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pkgfile $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo pacman -S $COMMAND_LIBS" + # dnf + elif which dnf &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do dnf whatprovides -q $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | grep -v 'Repo' | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo dnf install $COMMAND_LIBS" + # yum + elif which yum &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do yum whatprovides $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo yum install $COMMAND_LIBS" + # zypper + elif which zypper &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do zypper wp $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo zypper install $COMMAND_LIBS" + # emerge + elif which pfl &>/dev/null; then + LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` + COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pfl $LIBRARY; done` + COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` + INSTALL_CMD="sudo emerge $COMMAND_LIBS" + fi + + MESSAGE="Error: The launcher is missing the following libraries that it needs to work correctly:\n\t${DEPS_LIST}\nPlease install them from your distribution's package manager." + MESSAGE="$MESSAGE\n\nHint (please apply common sense): $INSTALL_CMD\n" + + printerror "$MESSAGE" + exit 1 +fi diff --git a/launcher/MainWindow.cpp b/launcher/MainWindow.cpp index 0d77ed19..84d72d5b 100644 --- a/launcher/MainWindow.cpp +++ b/launcher/MainWindow.cpp @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "MultiMC.h" +#include "Launcher.h" #include "BuildConfig.h" #include "MainWindow.h" @@ -267,7 +267,7 @@ public: actionAddInstance = TranslatedAction(MainWindow); actionAddInstance->setObjectName(QStringLiteral("actionAddInstance")); - actionAddInstance->setIcon(MMC->getThemedIcon("new")); + actionAddInstance->setIcon(LAUNCHER->getThemedIcon("new")); actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instance")); actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance.")); all_actions.append(&actionAddInstance); @@ -280,7 +280,7 @@ public: actionViewInstanceFolder = TranslatedAction(MainWindow); actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder")); - actionViewInstanceFolder->setIcon(MMC->getThemedIcon("viewfolder")); + actionViewInstanceFolder->setIcon(LAUNCHER->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); @@ -288,7 +288,7 @@ public: actionViewCentralModsFolder = TranslatedAction(MainWindow); actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); - actionViewCentralModsFolder->setIcon(MMC->getThemedIcon("centralmods")); + actionViewCentralModsFolder->setIcon(LAUNCHER->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); @@ -300,7 +300,7 @@ public: foldersMenuButton->setMenu(foldersMenu); foldersMenuButton->setPopupMode(QToolButton::InstantPopup); foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - foldersMenuButton->setIcon(MMC->getThemedIcon("viewfolder")); + foldersMenuButton->setIcon(LAUNCHER->getThemedIcon("viewfolder")); foldersMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&foldersMenuButton); QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow); @@ -309,7 +309,7 @@ public: actionSettings = TranslatedAction(MainWindow); actionSettings->setObjectName(QStringLiteral("actionSettings")); - actionSettings->setIcon(MMC->getThemedIcon("settings")); + actionSettings->setIcon(LAUNCHER->getThemedIcon("settings")); actionSettings->setMenuRole(QAction::PreferencesRole); actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Settings")); actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings.")); @@ -322,7 +322,7 @@ public: if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { actionReportBug = TranslatedAction(MainWindow); actionReportBug->setObjectName(QStringLiteral("actionReportBug")); - actionReportBug->setIcon(MMC->getThemedIcon("bug")); + actionReportBug->setIcon(LAUNCHER->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 MultiMC.")); all_actions.append(&actionReportBug); @@ -332,7 +332,7 @@ public: if (!BuildConfig.DISCORD_URL.isEmpty()) { actionDISCORD = TranslatedAction(MainWindow); actionDISCORD->setObjectName(QStringLiteral("actionDISCORD")); - actionDISCORD->setIcon(MMC->getThemedIcon("discord")); + actionDISCORD->setIcon(LAUNCHER->getThemedIcon("discord")); actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord")); actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC discord voice chat.")); all_actions.append(&actionDISCORD); @@ -342,7 +342,7 @@ public: if (!BuildConfig.SUBREDDIT_URL.isEmpty()) { actionREDDIT = TranslatedAction(MainWindow); actionREDDIT->setObjectName(QStringLiteral("actionREDDIT")); - actionREDDIT->setIcon(MMC->getThemedIcon("reddit-alien")); + actionREDDIT->setIcon(LAUNCHER->getThemedIcon("reddit-alien")); actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Reddit")); actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC subreddit.")); all_actions.append(&actionREDDIT); @@ -351,7 +351,7 @@ public: actionAbout = TranslatedAction(MainWindow); actionAbout->setObjectName(QStringLiteral("actionAbout")); - actionAbout->setIcon(MMC->getThemedIcon("about")); + actionAbout->setIcon(LAUNCHER->getThemedIcon("about")); actionAbout->setMenuRole(QAction::AboutRole); actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "About MultiMC")); actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about MultiMC.")); @@ -364,7 +364,7 @@ public: helpMenuButton->setMenu(helpMenu); helpMenuButton->setPopupMode(QToolButton::InstantPopup); helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - helpMenuButton->setIcon(MMC->getThemedIcon("help")); + helpMenuButton->setIcon(LAUNCHER->getThemedIcon("help")); helpMenuButton->setFocusPolicy(Qt::NoFocus); all_toolbuttons.append(&helpMenuButton); QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow); @@ -375,7 +375,7 @@ public: { actionCheckUpdate = TranslatedAction(MainWindow); actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); - actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate")); + actionCheckUpdate->setIcon(LAUNCHER->getThemedIcon("checkupdate")); actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Update")); actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for MultiMC.")); all_actions.append(&actionCheckUpdate); @@ -386,7 +386,7 @@ public: actionPatreon = TranslatedAction(MainWindow); actionPatreon->setObjectName(QStringLiteral("actionPatreon")); - actionPatreon->setIcon(MMC->getThemedIcon("patreon")); + actionPatreon->setIcon(LAUNCHER->getThemedIcon("patreon")); actionPatreon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Support MultiMC")); actionPatreon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC Patreon page.")); all_actions.append(&actionPatreon); @@ -395,7 +395,7 @@ public: actionCAT = TranslatedAction(MainWindow); actionCAT->setObjectName(QStringLiteral("actionCAT")); actionCAT->setCheckable(true); - actionCAT->setIcon(MMC->getThemedIcon("cat")); + actionCAT->setIcon(LAUNCHER->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); @@ -408,7 +408,7 @@ public: actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Accounts")); // FIXME: no tooltip! actionManageAccounts->setCheckable(false); - actionManageAccounts->setIcon(MMC->getThemedIcon("accounts")); + actionManageAccounts->setIcon(LAUNCHER->getThemedIcon("accounts")); all_actions.append(&actionManageAccounts); all_toolbars.append(&mainToolBar); @@ -435,7 +435,7 @@ public: actionMoreNews = TranslatedAction(MainWindow); actionMoreNews->setObjectName(QStringLiteral("actionMoreNews")); - actionMoreNews->setIcon(MMC->getThemedIcon("news")); + actionMoreNews->setIcon(LAUNCHER->getThemedIcon("news")); actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news...")); actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC development blog to read more news about MultiMC.")); all_actions.append(&actionMoreNews); @@ -467,7 +467,7 @@ public: changeIconButton = new LabeledToolButton(MainWindow); changeIconButton->setObjectName(QStringLiteral("changeIconButton")); - changeIconButton->setIcon(MMC->getThemedIcon("news")); + changeIconButton->setIcon(LAUNCHER->getThemedIcon("news")); changeIconButton->setToolTip(actionChangeInstIcon->toolTip()); changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); instanceToolBar->addWidget(changeIconButton); @@ -578,7 +578,7 @@ public: actionCopyInstance = TranslatedAction(MainWindow); actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance")); - actionCopyInstance->setIcon(MMC->getThemedIcon("copy")); + actionCopyInstance->setIcon(LAUNCHER->getThemedIcon("copy")); actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Copy Instance")); actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance.")); all_actions.append(&actionCopyInstance); @@ -595,7 +595,7 @@ public: MainWindow->setObjectName(QStringLiteral("MainWindow")); } MainWindow->resize(800, 600); - MainWindow->setWindowIcon(MMC->getThemedIcon("logo")); + MainWindow->setWindowIcon(LAUNCHER->getThemedIcon("logo")); MainWindow->setWindowTitle("MultiMC 5"); #ifndef QT_NO_ACCESSIBILITY MainWindow->setAccessibleName("MultiMC"); @@ -672,7 +672,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow { m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL)); newsLabel = new QToolButton(); - newsLabel->setIcon(MMC->getThemedIcon("news")); + newsLabel->setIcon(LAUNCHER->getThemedIcon("news")); newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); newsLabel->setFocusPolicy(Qt::NoFocus); @@ -699,20 +699,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(view, &GroupView::droppedURLs, this, &MainWindow::droppedURLs, Qt::QueuedConnection); proxymodel = new InstanceProxyModel(this); - proxymodel->setSourceModel(MMC->instances().get()); + proxymodel->setSourceModel(LAUNCHER->instances().get()); proxymodel->sort(0); connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged); view->setModel(proxymodel); view->setSourceOfGroupCollapseStatus([](const QString & groupName)->bool { - return MMC->instances()->isGroupCollapsed(groupName); + return LAUNCHER->instances()->isGroupCollapsed(groupName); }); - connect(view, &GroupView::groupStateChanged, MMC->instances().get(), &InstanceList::on_GroupStateChanged); + connect(view, &GroupView::groupStateChanged, LAUNCHER->instances().get(), &InstanceList::on_GroupStateChanged); ui->horizontalLayout->addWidget(view); } // The cat background { - bool cat_enable = MMC->settings()->get("TheCat").toBool(); + bool cat_enable = LAUNCHER->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))); @@ -725,16 +725,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(MMC->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); + connect(LAUNCHER->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); // model reset -> selection is invalid. All the instance pointers are wrong. - connect(MMC->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); + connect(LAUNCHER->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); // handle newly added instances - connect(MMC->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); + connect(LAUNCHER->instances().get(), &InstanceList::instanceSelectRequest, this, &MainWindow::instanceSelectRequest); // When the global settings page closes, we want to know about it and update our state - connect(MMC, &MultiMC::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); + connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &MainWindow::globalSettingsClosed); m_statusLeft = new QLabel(tr("No instance selected"), this); m_statusCenter = new QLabel(tr("Total playtime: 0s."), this); @@ -754,7 +754,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow accountMenuButton->setMenu(accountMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - accountMenuButton->setIcon(MMC->getThemedIcon("noaccount")); + accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); QWidgetAction *accountMenuButtonAction = new QWidgetAction(this); accountMenuButtonAction->setDefaultWidget(accountMenuButton); @@ -765,14 +765,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( - MMC->accounts().get(), + LAUNCHER->accounts().get(), &AccountList::activeAccountChanged, [this] { activeAccountChanged(); } ); connect( - MMC->accounts().get(), + LAUNCHER->accounts().get(), &AccountList::listChanged, [this] { @@ -784,7 +784,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow activeAccountChanged(); // TODO: refresh accounts here? - // auto accounts = MMC->accounts(); + // auto accounts = LAUNCHER->accounts(); // load the news { @@ -795,20 +795,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow if(BuildConfig.UPDATER_ENABLED) { - bool updatesAllowed = MMC->updatesAreAllowed(); + bool updatesAllowed = LAUNCHER->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 = MMC->updateChecker(); + auto updater = LAUNCHER->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 (MMC->settings()->get("AutoUpdate").toBool() && updatesAllowed) + if (LAUNCHER->settings()->get("AutoUpdate").toBool() && updatesAllowed) { - updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false); + updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), false); } } @@ -823,7 +823,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow checker->checkForNotifications(); } - setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); // removing this looks stupid view->setFocus(); @@ -833,7 +833,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow void MainWindow::retranslateUi() { - std::shared_ptr accounts = MMC->accounts(); + std::shared_ptr accounts = LAUNCHER->accounts(); MinecraftAccountPtr active_account = accounts->activeAccount(); if(active_account) { auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse()); @@ -971,16 +971,16 @@ void MainWindow::updateToolsMenu() QAction *normalLaunchOffline = launchOfflineMenu->addAction(tr("Launch Offline")); connect(normalLaunch, &QAction::triggered, [this]() { - MMC->launch(m_selectedInstance, true); + LAUNCHER->launch(m_selectedInstance, true); }); connect(normalLaunchOffline, &QAction::triggered, [this]() { - MMC->launch(m_selectedInstance, false); + LAUNCHER->launch(m_selectedInstance, false); }); QString profilersTitle = tr("Profilers"); launchMenu->addSeparator()->setText(profilersTitle); launchOfflineMenu->addSeparator()->setText(profilersTitle); - for (auto profiler : MMC->profilers().values()) + for (auto profiler : LAUNCHER->profilers().values()) { QAction *profilerAction = launchMenu->addAction(profiler->name()); QAction *profilerOfflineAction = launchOfflineMenu->addAction(profiler->name()); @@ -997,11 +997,11 @@ void MainWindow::updateToolsMenu() { connect(profilerAction, &QAction::triggered, [this, profiler]() { - MMC->launch(m_selectedInstance, true, profiler.get()); + LAUNCHER->launch(m_selectedInstance, true, profiler.get()); }); connect(profilerOfflineAction, &QAction::triggered, [this, profiler]() { - MMC->launch(m_selectedInstance, false, profiler.get()); + LAUNCHER->launch(m_selectedInstance, false, profiler.get()); }); } } @@ -1013,7 +1013,7 @@ void MainWindow::repopulateAccountsMenu() { accountMenu->clear(); - std::shared_ptr accounts = MMC->accounts(); + std::shared_ptr accounts = LAUNCHER->accounts(); MinecraftAccountPtr active_account = accounts->activeAccount(); QString active_profileId = ""; @@ -1059,7 +1059,7 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(tr("No Default Account"), this); action->setCheckable(true); - action->setIcon(MMC->getThemedIcon("noaccount")); + action->setIcon(LAUNCHER->getThemedIcon("noaccount")); action->setData(""); if (active_profileId.isEmpty()) { action->setChecked(true); @@ -1099,7 +1099,7 @@ void MainWindow::changeActiveAccount() id = data.toString(); } - MMC->accounts()->setActiveAccount(id); + LAUNCHER->accounts()->setActiveAccount(id); activeAccountChanged(); } @@ -1108,7 +1108,7 @@ void MainWindow::activeAccountChanged() { repopulateAccountsMenu(); - MinecraftAccountPtr account = MMC->accounts()->activeAccount(); + MinecraftAccountPtr account = LAUNCHER->accounts()->activeAccount(); // FIXME: this needs adjustment for MSA if (account != nullptr && account->profileName() != "") @@ -1120,7 +1120,7 @@ void MainWindow::activeAccountChanged() } // Set the icon to the "no account" icon. - accountMenuButton->setIcon(MMC->getThemedIcon("noaccount")); + accountMenuButton->setIcon(LAUNCHER->getThemedIcon("noaccount")); accountMenuButton->setText(tr("Profiles")); } @@ -1182,7 +1182,7 @@ void MainWindow::updateNewsLabel() void MainWindow::updateAvailable(GoUpdate::Status status) { - if(!MMC->updatesAreAllowed()) + if(!LAUNCHER->updatesAreAllowed()) { updateNotAvailable(); return; @@ -1228,7 +1228,7 @@ QString intListToString(const QList &list) void MainWindow::notificationsChanged() { QList entries = m_notificationChecker->notificationEntries(); - QList shownNotifications = stringToIntList(MMC->settings()->get("ShownNotifications").toString()); + QList shownNotifications = stringToIntList(LAUNCHER->settings()->get("ShownNotifications").toString()); for (auto it = entries.begin(); it != entries.end(); ++it) { NotificationChecker::NotificationEntry entry = *it; @@ -1241,20 +1241,20 @@ void MainWindow::notificationsChanged() } } } - MMC->settings()->set("ShownNotifications", intListToString(shownNotifications)); + LAUNCHER->settings()->set("ShownNotifications", intListToString(shownNotifications)); } void MainWindow::downloadUpdates(GoUpdate::Status status) { - if(!MMC->updatesAreAllowed()) + if(!LAUNCHER->updatesAreAllowed()) { return; } qDebug() << "Downloading updates."; ProgressDialog updateDlg(this); - status.rootPath = MMC->root(); + status.rootPath = LAUNCHER->root(); - auto dlPath = FS::PathCombine(MMC->root(), "update", "XXXXXX"); + auto dlPath = FS::PathCombine(LAUNCHER->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(); @@ -1267,10 +1267,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). */ - MMC->updateIsRunning(true); - UpdateController update(this, MMC->root(), updateTask.updateFilesDir(), updateTask.operations()); + LAUNCHER->updateIsRunning(true); + UpdateController update(this, LAUNCHER->root(), updateTask.updateFilesDir(), updateTask.operations()); update.installUpdates(); - MMC->updateIsRunning(false); + LAUNCHER->updateIsRunning(false); } else { @@ -1281,7 +1281,7 @@ void MainWindow::downloadUpdates(GoUpdate::Status status) void MainWindow::onCatToggled(bool state) { setCatBackground(state); - MMC->settings()->set("TheCat", state); + LAUNCHER->settings()->set("TheCat", state); } namespace { @@ -1339,7 +1339,7 @@ void MainWindow::runModalTask(Task *task) void MainWindow::instanceFromInstanceTask(InstanceTask *rawTask) { - unique_qobject_ptr task(MMC->instances()->wrapInstanceTask(rawTask)); + unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(rawTask)); runModalTask(task.get()); } @@ -1356,7 +1356,7 @@ void MainWindow::on_actionCopyInstance_triggered() copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); - unique_qobject_ptr task(MMC->instances()->wrapInstanceTask(copyTask)); + unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(copyTask)); runModalTask(task.get()); } @@ -1364,7 +1364,7 @@ void MainWindow::finalizeInstance(InstancePtr inst) { view->updateGeometries(); setSelectedInstanceById(inst->id()); - if (MMC->accounts()->anyAccountIsValid()) + if (LAUNCHER->accounts()->anyAccountIsValid()) { ProgressDialog loadDialog(this); auto update = inst->createUpdateTask(Net::Mode::Online); @@ -1407,14 +1407,14 @@ void MainWindow::addInstance(QString url) if(groupName.isEmpty()) { - groupName = MMC->settings()->get("LastUsedGroupForNewInstance").toString(); + groupName = LAUNCHER->settings()->get("LastUsedGroupForNewInstance").toString(); } NewInstanceDialog newInstDlg(groupName, url, this); if (!newInstDlg.exec()) return; - MMC->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); + LAUNCHER->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); InstanceTask * creationTask = newInstDlg.extractTask(); if(creationTask) @@ -1465,7 +1465,7 @@ void MainWindow::on_actionChangeInstIcon_triggered() if (dlg.result() == QDialog::Accepted) { m_selectedInstance->setIconKey(dlg.selectedIconKey); - auto icon = MMC->icons()->getIcon(dlg.selectedIconKey); + auto icon = LAUNCHER->icons()->getIcon(dlg.selectedIconKey); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1475,7 +1475,7 @@ void MainWindow::iconUpdated(QString icon) { if (icon == m_currentInstIcon) { - auto icon = MMC->icons()->getIcon(m_currentInstIcon); + auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1484,7 +1484,7 @@ void MainWindow::iconUpdated(QString icon) void MainWindow::updateInstanceToolIcon(QString new_icon) { m_currentInstIcon = new_icon; - auto icon = MMC->icons()->getIcon(m_currentInstIcon); + auto icon = LAUNCHER->icons()->getIcon(m_currentInstIcon); ui->actionChangeInstIcon->setIcon(icon); ui->changeIconButton->setIcon(icon); } @@ -1493,7 +1493,7 @@ void MainWindow::setSelectedInstanceById(const QString &id) { if (id.isNull()) return; - const QModelIndex index = MMC->instances()->getInstanceIndexById(id); + const QModelIndex index = LAUNCHER->instances()->getInstanceIndexById(id); if (index.isValid()) { QModelIndex selectionIndex = proxymodel->mapFromSource(index); @@ -1509,8 +1509,8 @@ void MainWindow::on_actionChangeInstGroup_triggered() bool ok = false; InstanceId instId = m_selectedInstance->id(); - QString name(MMC->instances()->getInstanceGroup(instId)); - auto groups = MMC->instances()->getGroups(); + QString name(LAUNCHER->instances()->getInstanceGroup(instId)); + auto groups = LAUNCHER->instances()->getGroups(); groups.insert(0, ""); groups.sort(Qt::CaseInsensitive); int foo = groups.indexOf(name); @@ -1519,7 +1519,7 @@ void MainWindow::on_actionChangeInstGroup_triggered() name = name.simplified(); if (ok) { - MMC->instances()->setInstanceGroup(instId, name); + LAUNCHER->instances()->setInstanceGroup(instId, name); } } @@ -1541,25 +1541,25 @@ void MainWindow::deleteGroup() .arg(groupName), QMessageBox::Yes | QMessageBox::No); if(reply == QMessageBox::Yes) { - MMC->instances()->deleteGroup(groupName); + LAUNCHER->instances()->deleteGroup(groupName); } } } void MainWindow::on_actionViewInstanceFolder_triggered() { - QString str = MMC->settings()->get("InstanceDir").toString(); + QString str = LAUNCHER->settings()->get("InstanceDir").toString(); DesktopServices::openDirectory(str); } void MainWindow::refreshInstances() { - MMC->instances()->loadList(); + LAUNCHER->instances()->loadList(); } void MainWindow::on_actionViewCentralModsFolder_triggered() { - DesktopServices::openDirectory(MMC->settings()->get("CentralModsDir").toString(), true); + DesktopServices::openDirectory(LAUNCHER->settings()->get("CentralModsDir").toString(), true); } void MainWindow::on_actionConfig_Folder_triggered() @@ -1575,8 +1575,8 @@ void MainWindow::checkForUpdates() { if(BuildConfig.UPDATER_ENABLED) { - auto updater = MMC->updateChecker(); - updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), true); + auto updater = LAUNCHER->updateChecker(); + updater->checkForUpdate(LAUNCHER->settings()->get("UpdateChannel").toString(), true); } else { @@ -1586,13 +1586,13 @@ void MainWindow::checkForUpdates() void MainWindow::on_actionSettings_triggered() { - MMC->ShowGlobalSettings(this, "global-settings"); + LAUNCHER->ShowGlobalSettings(this, "global-settings"); } void MainWindow::globalSettingsClosed() { // FIXME: quick HACK to make this work. improve, optimize. - MMC->instances()->loadList(); + LAUNCHER->instances()->loadList(); proxymodel->invalidate(); proxymodel->sort(0); updateToolsMenu(); @@ -1601,32 +1601,32 @@ void MainWindow::globalSettingsClosed() void MainWindow::on_actionInstanceSettings_triggered() { - MMC->showInstanceWindow(m_selectedInstance, "settings"); + LAUNCHER->showInstanceWindow(m_selectedInstance, "settings"); } void MainWindow::on_actionEditInstNotes_triggered() { - MMC->showInstanceWindow(m_selectedInstance, "notes"); + LAUNCHER->showInstanceWindow(m_selectedInstance, "notes"); } void MainWindow::on_actionWorlds_triggered() { - MMC->showInstanceWindow(m_selectedInstance, "worlds"); + LAUNCHER->showInstanceWindow(m_selectedInstance, "worlds"); } void MainWindow::on_actionEditInstance_triggered() { - MMC->showInstanceWindow(m_selectedInstance); + LAUNCHER->showInstanceWindow(m_selectedInstance); } void MainWindow::on_actionScreenshots_triggered() { - MMC->showInstanceWindow(m_selectedInstance, "screenshots"); + LAUNCHER->showInstanceWindow(m_selectedInstance, "screenshots"); } void MainWindow::on_actionManageAccounts_triggered() { - MMC->ShowGlobalSettings(this, "accounts"); + LAUNCHER->ShowGlobalSettings(this, "accounts"); } void MainWindow::on_actionReportBug_triggered() @@ -1680,7 +1680,7 @@ void MainWindow::on_actionDeleteInstance_triggered() )->exec(); if (response == QMessageBox::Yes) { - MMC->instances()->deleteInstance(id); + LAUNCHER->instances()->deleteInstance(id); } } @@ -1728,8 +1728,8 @@ void MainWindow::on_actionViewSelectedMCFolder_triggered() void MainWindow::closeEvent(QCloseEvent *event) { // Save the window state and geometry. - MMC->settings()->set("MainWindowState", saveState().toBase64()); - MMC->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("MainWindowState", saveState().toBase64()); + LAUNCHER->settings()->set("MainWindowGeometry", saveGeometry().toBase64()); event->accept(); emit isClosing(); } @@ -1748,7 +1748,7 @@ void MainWindow::instanceActivated(QModelIndex index) if (!index.isValid()) return; QString id = index.data(InstanceList::InstanceIDRole).toString(); - InstancePtr inst = MMC->instances()->getInstanceById(id); + InstancePtr inst = LAUNCHER->instances()->getInstanceById(id); if (!inst) return; @@ -1763,24 +1763,24 @@ void MainWindow::on_actionLaunchInstance_triggered() } if(m_selectedInstance->isRunning()) { - MMC->kill(m_selectedInstance); + LAUNCHER->kill(m_selectedInstance); } else { - MMC->launch(m_selectedInstance); + LAUNCHER->launch(m_selectedInstance); } } void MainWindow::activateInstance(InstancePtr instance) { - MMC->launch(instance); + LAUNCHER->launch(instance); } void MainWindow::on_actionLaunchInstanceOffline_triggered() { if (m_selectedInstance) { - MMC->launch(m_selectedInstance, false); + LAUNCHER->launch(m_selectedInstance, false); } } @@ -1804,12 +1804,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & { if (!current.isValid()) { - MMC->settings()->set("SelectedInstance", QString()); + LAUNCHER->settings()->set("SelectedInstance", QString()); selectionBad(); return; } QString id = current.data(InstanceList::InstanceIDRole).toString(); - m_selectedInstance = MMC->instances()->getInstanceById(id); + m_selectedInstance = LAUNCHER->instances()->getInstanceById(id); if (m_selectedInstance) { ui->instanceToolBar->setEnabled(true); @@ -1832,12 +1832,12 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & updateToolsMenu(); - MMC->settings()->set("SelectedInstance", m_selectedInstance->id()); + LAUNCHER->settings()->set("SelectedInstance", m_selectedInstance->id()); } else { ui->instanceToolBar->setEnabled(false); - MMC->settings()->set("SelectedInstance", QString()); + LAUNCHER->settings()->set("SelectedInstance", QString()); selectionBad(); return; } @@ -1869,12 +1869,12 @@ void MainWindow::selectionBad() updateInstanceToolIcon("infinity"); // ...and then see if we can enable the previously selected instance - setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString()); + setSelectedInstanceById(LAUNCHER->settings()->get("SelectedInstance").toString()); } void MainWindow::checkInstancePathForProblems() { - QString instanceFolder = MMC->settings()->get("InstanceDir").toString(); + QString instanceFolder = LAUNCHER->settings()->get("InstanceDir").toString(); if (FS::checkProblemticPathJava(QDir(instanceFolder))) { QMessageBox warning(this); @@ -1909,7 +1909,7 @@ void MainWindow::checkInstancePathForProblems() void MainWindow::updateStatusCenter() { - int timeplayed = MMC->instances()->getTotalPlayTime(); + int timeplayed = LAUNCHER->instances()->getTotalPlayTime(); int minutesTotal = timeplayed / 60; int seconds = timeplayed % 60; int minutes = minutesTotal % 60; diff --git a/launcher/MultiMC.cpp b/launcher/MultiMC.cpp deleted file mode 100644 index c532ce82..00000000 --- a/launcher/MultiMC.cpp +++ /dev/null @@ -1,1493 +0,0 @@ -#include "MultiMC.h" -#include "BuildConfig.h" -#include "MainWindow.h" -#include "InstanceWindow.h" - -#include "groupview/AccessibleGroupView.h" -#include - -#include "pages/BasePageProvider.h" -#include "pages/global/MultiMCPage.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 "setupwizard/SetupWizard.h" -#include "setupwizard/LanguageWizardPage.h" -#include "setupwizard/JavaWizardPage.h" -#include "setupwizard/AnalyticsWizardPage.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialogs/CustomMessageBox.h" -#include "InstanceList.h" - -#include -#include "icons/IconList.h" -#include "net/HttpMetaCache.h" -#include "Env.h" - -#include "java/JavaUtils.h" - -#include "updater/UpdateChecker.h" - -#include "tools/JProfiler.h" -#include "tools/JVisualVM.h" -#include "tools/MCEditTool.h" - -#include -#include "settings/INISettingsObject.h" -#include "settings/Setting.h" - -#include "translations/TranslationsModel.h" - -#include -#include -#include -#include - -#include -#include - -#include "pagedialog/PageDialog.h" - - -#if defined Q_OS_WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#endif - -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -static const QLatin1String liveCheckFile("live.check"); - -using namespace Commandline; - -#define MACOS_HINT "If you are on macOS Sierra, you might have to move MultiMC.app to your /Applications or ~/Applications folder. "\ - "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ - "\n" - -namespace { -void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ - const char *levels = "DWCFIS"; - const QString format("%1 %2 %3\n"); - - qint64 msecstotal = MMC->timeSinceStart(); - qint64 seconds = msecstotal / 1000; - qint64 msecs = msecstotal % 1000; - QString foo; - char buf[1025] = {0}; - ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs); - - QString out = format.arg(buf).arg(levels[type]).arg(msg); - - MMC->logFile->write(out.toUtf8()); - MMC->logFile->flush(); - QTextStream(stderr) << out.toLocal8Bit(); - fflush(stderr); -} - -QString getIdealPlatform(QString currentPlatform) { - auto info = Sys::getKernelInfo(); - switch(info.kernelType) { - case Sys::KernelType::Darwin: { - if(info.kernelMajor >= 17) { - // macOS 10.13 or newer - return "osx64-5.15.2"; - } - else { - // macOS 10.12 or older - return "osx64"; - } - } - case Sys::KernelType::Windows: { - // FIXME: 5.15.2 is not stable on Windows, due to a large number of completely unpredictable and hard to reproduce issues - break; -/* - if(info.kernelMajor == 6 && info.kernelMinor >= 1) { - // Windows 7 - return "win32-5.15.2"; - } - else if (info.kernelMajor > 6) { - // Above Windows 7 - return "win32-5.15.2"; - } - else { - // Below Windows 7 - return "win32"; - } -*/ - } - case Sys::KernelType::Undetermined: - case Sys::KernelType::Linux: { - break; - } - } - return currentPlatform; -} - -} - -MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) -{ -#if defined Q_OS_WIN32 - // attach the parent console - if(AttachConsole(ATTACH_PARENT_PROCESS)) - { - // if attach succeeds, reopen and sync all the i/o - if(freopen("CON", "w", stdout)) - { - std::cout.sync_with_stdio(); - } - if(freopen("CON", "w", stderr)) - { - std::cerr.sync_with_stdio(); - } - if(freopen("CON", "r", stdin)) - { - std::cin.sync_with_stdio(); - } - auto out = GetStdHandle (STD_OUTPUT_HANDLE); - DWORD written; - const char * endline = "\n"; - WriteConsole(out, endline, strlen(endline), &written, NULL); - consoleAttached = true; - } -#endif - setOrganizationName("MultiMC"); - setOrganizationDomain("multimc.org"); - setApplicationName("MultiMC5"); - setApplicationDisplayName("MultiMC 5"); - setApplicationVersion(BuildConfig.printableVersionString()); - - startTime = QDateTime::currentDateTime(); - -#ifdef Q_OS_LINUX - { - QFile osrelease("/proc/sys/kernel/osrelease"); - if (osrelease.open(QFile::ReadOnly | QFile::Text)) { - QTextStream in(&osrelease); - auto contents = in.readAll(); - if( - contents.contains("WSL", Qt::CaseInsensitive) || - contents.contains("Microsoft", Qt::CaseInsensitive) - ) { - showFatalErrorMessage( - "Unsupported system detected!", - "Linux-on-Windows distributions are not supported.\n\n" - "Please use the Windows MultiMC binary when playing on Windows." - ); - return; - } - } - } -#endif - - // Don't quit on hiding the last window - this->setQuitOnLastWindowClosed(false); - - // Commandline parsing - QHash args; - { - Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals); - - // --help - parser.addSwitch("help"); - parser.addShortOpt("help", 'h'); - parser.addDocumentation("help", "Display this help and exit."); - // --version - parser.addSwitch("version"); - parser.addShortOpt("version", 'V'); - parser.addDocumentation("version", "Display program version and exit."); - // --dir - parser.addOption("dir"); - parser.addShortOpt("dir", 'd'); - parser.addDocumentation("dir", "Use the supplied folder as MultiMC root instead of " - "the binary location (use '.' for current)"); - // --launch - parser.addOption("launch"); - parser.addShortOpt("launch", 'l'); - parser.addDocumentation("launch", "Launch the specified instance (by instance ID)"); - // --server - parser.addOption("server"); - parser.addShortOpt("server", 's'); - parser.addDocumentation("server", "Join the specified server on launch " - "(only valid in combination with --launch)"); - // --alive - parser.addSwitch("alive"); - parser.addDocumentation("alive", "Write a small '" + liveCheckFile + "' file after MultiMC starts"); - // --import - parser.addOption("import"); - parser.addShortOpt("import", 'I'); - parser.addDocumentation("import", "Import instance from specified zip (local path or URL)"); - - // parse the arguments - try - { - args = parser.parse(arguments()); - } - catch (const ParsingError &e) - { - std::cerr << "CommandLineError: " << e.what() << std::endl; - if(argc > 0) - std::cerr << "Try '" << argv[0] << " -h' to get help on MultiMC's command line parameters." - << std::endl; - m_status = MultiMC::Failed; - return; - } - - // display help and exit - if (args["help"].toBool()) - { - std::cout << qPrintable(parser.compileHelp(arguments()[0])); - m_status = MultiMC::Succeeded; - return; - } - - // display version and exit - if (args["version"].toBool()) - { - std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; - std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; - m_status = MultiMC::Succeeded; - return; - } - } - m_instanceIdToLaunch = args["launch"].toString(); - m_serverToJoin = args["server"].toString(); - m_liveCheck = args["alive"].toBool(); - m_zipToImport = args["import"].toUrl(); - - QString origcwdPath = QDir::currentPath(); - QString binPath = applicationDirPath(); - QString adjustedBy; - QString dataPath; - // change folder - QString dirParam = args["dir"].toString(); - if (!dirParam.isEmpty()) - { - // the dir param. it makes multimc data path point to whatever the user specified - // on command line - adjustedBy += "Command line " + dirParam; - dataPath = dirParam; - } - else - { -#ifdef MULTIMC_LINUX_DATADIR - QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); - if (xdgDataHome.isEmpty()) - xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); - dataPath = xdgDataHome + "/multimc"; - adjustedBy += "XDG standard " + dataPath; -#elif defined(Q_OS_MAC) - QDir foo(FS::PathCombine(applicationDirPath(), "../../Data")); - dataPath = foo.absolutePath(); - adjustedBy += "Fallback to special Mac location " + dataPath; -#else - dataPath = applicationDirPath(); - adjustedBy += "Fallback to binary path " + dataPath; -#endif - } - - if (!FS::ensureFolderPathExists(dataPath)) - { - showFatalErrorMessage( - "MultiMC data folder could not be created.", - "MultiMC data folder could not be created.\n" - "\n" -#if defined(Q_OS_MAC) - MACOS_HINT -#endif - "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - if (!QDir::setCurrent(dataPath)) - { - showFatalErrorMessage( - "MultiMC data folder could not be opened.", - "MultiMC data folder could not be opened.\n" - "\n" -#if defined(Q_OS_MAC) - MACOS_HINT -#endif - "Make sure you have the right permissions to the MultiMC data folder.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - - if(m_instanceIdToLaunch.isEmpty() && !m_serverToJoin.isEmpty()) - { - std::cerr << "--server can only be used in combination with --launch!" << std::endl; - m_status = MultiMC::Failed; - return; - } - -#if defined(Q_OS_MAC) - // move user data to new location if on macOS and it still exists in Contents/MacOS - QDir fi(applicationDirPath()); - QString originalData = fi.absolutePath(); - // if the config file exists in Contents/MacOS, then user data is still there and needs to moved - if (QFileInfo::exists(FS::PathCombine(originalData, "multimc.cfg"))) - { - if (!QFileInfo::exists(FS::PathCombine(originalData, "dontmovemacdata"))) - { - QMessageBox::StandardButton askMoveDialogue; - askMoveDialogue = QMessageBox::question(nullptr, "MultiMC 5", "Would you like to move application data to a new data location? It will improve MultiMC's performance, but if you switch to older versions it will look like instances have disappeared. If you select no, you can migrate later in settings. You should select yes unless you're commonly switching between different versions of MultiMC (eg. develop and stable).", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - if (askMoveDialogue == QMessageBox::Yes) - { - qDebug() << "On macOS and found config file in old location, moving user data..."; - QDir dir; - QStringList dataFiles { - "*.log", // MultiMC-@.log - "accounts.json", - "accounts", - "assets", - "cache", - "icons", - "instances", - "libraries", - "meta", - "metacache", - "mods", - "multimc.cfg", - "themes", - "translations" - }; - QDirIterator files(originalData, dataFiles); - while (files.hasNext()) { - QString filePath(files.next()); - QString fileName(files.fileName()); - if (!dir.rename(filePath, FS::PathCombine(dataPath, fileName))) - { - qWarning() << "Failed to move " << fileName; - } - } - } - else - { - dataPath = originalData; - QDir::setCurrent(dataPath); - QFile file(originalData + "/dontmovemacdata"); - file.open(QIODevice::WriteOnly); - } - } - else - { - dataPath = originalData; - QDir::setCurrent(dataPath); - } - } -#endif - - /* - * Establish the mechanism for communication with an already running MultiMC that uses the same data path. - * If there is one, tell it what the user actually wanted to do and exit. - * We want to initialize this before logging to avoid messing with the log of a potential already running copy. - */ - auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString()); - { - // 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, &MultiMC::messageReceived); - if(m_peerInstance->isClient()) - { - int timeout = 2000; - - if(m_instanceIdToLaunch.isEmpty()) - { - m_peerInstance->sendMessage("activate", timeout); - - if(!m_zipToImport.isEmpty()) - { - m_peerInstance->sendMessage("import " + m_zipToImport.toString(), timeout); - } - } - else - { - if(!m_serverToJoin.isEmpty()) - { - m_peerInstance->sendMessage( - "launch-with-server " + m_instanceIdToLaunch + " " + m_serverToJoin, timeout); - } - else - { - m_peerInstance->sendMessage("launch " + m_instanceIdToLaunch, timeout); - } - } - m_status = MultiMC::Succeeded; - return; - } - } - - // init the logger - { - static const QString logBase = "MultiMC-%0.log"; - auto moveFile = [](const QString &oldName, const QString &newName) - { - QFile::remove(newName); - QFile::copy(oldName, newName); - QFile::remove(oldName); - }; - - moveFile(logBase.arg(3), logBase.arg(4)); - moveFile(logBase.arg(2), logBase.arg(3)); - moveFile(logBase.arg(1), logBase.arg(2)); - moveFile(logBase.arg(0), logBase.arg(1)); - - logFile = std::unique_ptr(new QFile(logBase.arg(0))); - if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - { - showFatalErrorMessage( - "MultiMC data folder is not writable!", - "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n" - "\n" - #if defined(Q_OS_MAC) - MACOS_HINT - #endif - "Make sure you have write permissions to the MultiMC data folder.\n" - "\n" - "MultiMC cannot continue until you fix this problem." - ); - return; - } - qInstallMessageHandler(appDebugOutput); - qDebug() << "<> Log initialized."; - } - - // Set up paths - { - // Root path is used for updates. -#ifdef Q_OS_LINUX - QDir foo(FS::PathCombine(binPath, "..")); - m_rootPath = foo.absolutePath(); -#elif defined(Q_OS_WIN32) - m_rootPath = binPath; -#elif defined(Q_OS_MAC) - QDir foo(FS::PathCombine(binPath, "../..")); - m_rootPath = foo.absolutePath(); - // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) - FS::updateTimestamp(m_rootPath); -#endif - -#ifdef MULTIMC_JARS_LOCATION - ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) ); -#endif - - qDebug() << "MultiMC 5, (c) 2013-2021 MultiMC Contributors"; - qDebug() << "Version : " << BuildConfig.printableVersionString(); - qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; - qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; - if (adjustedBy.size()) - { - qDebug() << "Work dir before adjustment : " << origcwdPath; - qDebug() << "Work dir after adjustment : " << QDir::currentPath(); - qDebug() << "Adjusted by : " << adjustedBy; - } - else - { - qDebug() << "Work dir : " << QDir::currentPath(); - } - qDebug() << "Binary path : " << binPath; - qDebug() << "Application root path : " << m_rootPath; - if(!m_instanceIdToLaunch.isEmpty()) - { - qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch; - } - if(!m_serverToJoin.isEmpty()) - { - qDebug() << "Address of server to join :" << m_serverToJoin; - } - qDebug() << "<> Paths set."; - } - - do // once - { - if(m_liveCheck) - { - QFile check(liveCheckFile); - if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - qWarning() << "Could not open" << liveCheckFile << "for writing!"; - break; - } - auto payload = appID.toString().toUtf8(); - if(check.write(payload) != payload.size()) - { - qWarning() << "Could not write into" << liveCheckFile << "!"; - check.remove(); - break; - } - check.close(); - } - } while(false); - - // Initialize application settings - { - m_settings.reset(new INISettingsObject("multimc.cfg", this)); - // Updates - m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL); - m_settings->registerSetting("AutoUpdate", true); - - // Theming - m_settings->registerSetting("IconTheme", QString("multimc")); - m_settings->registerSetting("ApplicationTheme", QString("system")); - - // Notifications - m_settings->registerSetting("ShownNotifications", QString()); - - // Remembered state - m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); - - QString defaultMonospace; - int defaultSize = 11; -#ifdef Q_OS_WIN32 - defaultMonospace = "Courier"; - defaultSize = 10; -#elif defined(Q_OS_MAC) - defaultMonospace = "Menlo"; -#else - defaultMonospace = "Monospace"; -#endif - - // resolve the font so the default actually matches - QFont consoleFont; - consoleFont.setFamily(defaultMonospace); - consoleFont.setStyleHint(QFont::Monospace); - consoleFont.setFixedPitch(true); - QFontInfo consoleFontInfo(consoleFont); - QString resolvedDefaultMonospace = consoleFontInfo.family(); - QFont resolvedFont(resolvedDefaultMonospace); - qDebug() << "Detected default console font:" << resolvedDefaultMonospace - << ", substitutions:" << resolvedFont.substitutions().join(','); - - m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace); - m_settings->registerSetting("ConsoleFontSize", defaultSize); - m_settings->registerSetting("ConsoleMaxLines", 100000); - m_settings->registerSetting("ConsoleOverflowStop", true); - - // Folders - m_settings->registerSetting("InstanceDir", "instances"); - m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods"); - m_settings->registerSetting("IconsDir", "icons"); - - // Editors - m_settings->registerSetting("JsonEditor", QString()); - - // Language - m_settings->registerSetting("Language", QString()); - - // Console - m_settings->registerSetting("ShowConsole", false); - m_settings->registerSetting("AutoCloseConsole", false); - m_settings->registerSetting("ShowConsoleOnError", true); - m_settings->registerSetting("LogPrePostOutput", true); - - // Window Size - m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false); - m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854); - m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480); - - // Proxy Settings - m_settings->registerSetting("ProxyType", "None"); - m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1"); - m_settings->registerSetting("ProxyPort", 8080); - m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, ""); - m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, ""); - - // Memory - m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); - m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024); - m_settings->registerSetting("PermGen", 128); - - // Java Settings - m_settings->registerSetting("JavaPath", ""); - m_settings->registerSetting("JavaTimestamp", 0); - m_settings->registerSetting("JavaArchitecture", ""); - m_settings->registerSetting("JavaVersion", ""); - m_settings->registerSetting("JavaVendor", ""); - m_settings->registerSetting("LastHostname", ""); - m_settings->registerSetting("JvmArgs", ""); - - // Native library workarounds - m_settings->registerSetting("UseNativeOpenAL", false); - m_settings->registerSetting("UseNativeGLFW", false); - - // Game time - m_settings->registerSetting("ShowGameTime", true); - m_settings->registerSetting("RecordGameTime", true); - - // Minecraft launch method - m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); - - // Wrapper command for launch - m_settings->registerSetting("WrapperCommand", ""); - - // Custom Commands - m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, ""); - m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, ""); - - // The cat - m_settings->registerSetting("TheCat", false); - - m_settings->registerSetting("InstSortMode", "Name"); - m_settings->registerSetting("SelectedInstance", QString()); - - // Window state and geometry - m_settings->registerSetting("MainWindowState", ""); - m_settings->registerSetting("MainWindowGeometry", ""); - - m_settings->registerSetting("ConsoleWindowState", ""); - m_settings->registerSetting("ConsoleWindowGeometry", ""); - - m_settings->registerSetting("SettingsGeometry", ""); - - m_settings->registerSetting("PagedGeometry", ""); - - m_settings->registerSetting("NewInstanceGeometry", ""); - - m_settings->registerSetting("UpdateDialogGeometry", ""); - - // paste.ee API key - m_settings->registerSetting("PasteEEAPIKey", "multimc"); - - if(!BuildConfig.ANALYTICS_ID.isEmpty()) - { - // Analytics - m_settings->registerSetting("Analytics", true); - m_settings->registerSetting("AnalyticsSeen", 0); - m_settings->registerSetting("AnalyticsClientID", QString()); - } - - // Init page provider - { - m_globalSettingsProvider = std::make_shared(tr("Settings")); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); - } - qDebug() << "<> Settings loaded."; - } - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::installFactory(groupViewAccessibleFactory); -#endif /* !QT_NO_ACCESSIBILITY */ - - // load translations - { - m_translations.reset(new TranslationsModel("translations")); - auto bcp47Name = m_settings->get("Language").toString(); - m_translations->selectLanguage(bcp47Name); - qDebug() << "Your language is" << bcp47Name; - qDebug() << "<> Translations loaded."; - } - - // initialize the updater - if(BuildConfig.UPDATER_ENABLED) - { - 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)); - qDebug() << "<> Updater started."; - } - - // Instance icons - { - auto setting = MMC->settings()->getSetting("IconsDir"); - QStringList instFolders = - { - ":/icons/multimc/32x32/instances/", - ":/icons/multimc/50x50/instances/", - ":/icons/multimc/128x128/instances/", - ":/icons/multimc/scalable/instances/" - }; - m_icons.reset(new IconList(instFolders, setting->get().toString())); - connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) - { - m_icons->directoryChanged(value.toString()); - }); - ENV.registerIconList(m_icons); - qDebug() << "<> Instance icons intialized."; - } - - // Icon themes - { - // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! - // set icon theme search path! - auto searchPaths = QIcon::themeSearchPaths(); - searchPaths.append("iconthemes"); - QIcon::setThemeSearchPaths(searchPaths); - qDebug() << "<> Icon themes initialized."; - } - - // Initialize widget themes - { - auto insertTheme = [this](ITheme * theme) - { - m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); - }; - auto darkTheme = new DarkTheme(); - insertTheme(new SystemTheme()); - insertTheme(darkTheme); - insertTheme(new BrightTheme()); - insertTheme(new CustomTheme(darkTheme, "custom")); - qDebug() << "<> Widget themes initialized."; - } - - // initialize and load all instances - { - auto InstDirSetting = m_settings->getSetting("InstanceDir"); - // instance path: check for problems with '!' in instance path and warn the user in the log - // and remember that we have to show him a dialog when the gui starts (if it does so) - QString instDir = InstDirSetting->get().toString(); - qDebug() << "Instance path : " << instDir; - if (FS::checkProblemticPathJava(QDir(instDir))) - { - qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!"; - } - m_instances.reset(new InstanceList(m_settings, instDir, this)); - connect(InstDirSetting.get(), &Setting::SettingChanged, m_instances.get(), &InstanceList::on_InstFolderChanged); - qDebug() << "Loading Instances..."; - m_instances->loadList(); - qDebug() << "<> Instances loaded."; - } - - // and accounts - { - m_accounts.reset(new AccountList(this)); - qDebug() << "Loading accounts..."; - m_accounts->setListFilePath("accounts.json", true); - m_accounts->loadList(); - qDebug() << "<> Accounts loaded."; - } - - // init the http meta cache - { - ENV.initHttpMetaCache(); - qDebug() << "<> Cache initialized."; - } - - // init proxy settings - { - QString proxyTypeStr = settings()->get("ProxyType").toString(); - QString addr = settings()->get("ProxyAddr").toString(); - int port = settings()->get("ProxyPort").value(); - 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(); - - //FIXME: what to do with these? - m_profilers.insert("jprofiler", std::shared_ptr(new JProfilerFactory())); - m_profilers.insert("jvisualvm", std::shared_ptr(new JVisualVMFactory())); - for (auto profiler : m_profilers.values()) - { - profiler->registerSettings(m_settings); - } - - // Create the MCEdit thing... why is this here? - { - m_mcedit.reset(new MCEditTool(m_settings)); - } - - connect(this, &MultiMC::aboutToQuit, [this](){ - if(m_instances) - { - // save any remaining instance state - m_instances->saveNow(); - } - if(logFile) - { - logFile->flush(); - logFile->close(); - } - }); - - { - setIconTheme(settings()->get("IconTheme").toString()); - qDebug() << "<> Icon theme set."; - setApplicationTheme(settings()->get("ApplicationTheme").toString(), true); - qDebug() << "<> Application theme set."; - } - - // Initialize analytics - [this]() - { - const int analyticsVersion = 2; - if(BuildConfig.ANALYTICS_ID.isEmpty()) - { - return; - } - - auto analyticsSetting = m_settings->getSetting("Analytics"); - connect(analyticsSetting.get(), &Setting::SettingChanged, this, &MultiMC::analyticsSettingChanged); - QString clientID = m_settings->get("AnalyticsClientID").toString(); - if(clientID.isEmpty()) - { - clientID = QUuid::createUuid().toString(); - clientID.remove(QLatin1Char('{')); - clientID.remove(QLatin1Char('}')); - m_settings->set("AnalyticsClientID", clientID); - } - m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this); - m_analytics->setLogLevel(GAnalytics::Debug); - m_analytics->setAnonymizeIPs(true); - m_analytics->setNetworkAccessManager(&ENV.qnam()); - - if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version()) - { - qDebug() << "Analytics info not seen by user yet (or old version)."; - return; - } - if(!m_settings->get("Analytics").toBool()) - { - qDebug() << "Analytics disabled by user."; - return; - } - - m_analytics->enable(); - qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID; - }(); - - if(createSetupWizard()) - { - return; - } - performMainStartupAction(); -} - -bool MultiMC::createSetupWizard() -{ - bool javaRequired = [&]() - { - QString currentHostName = QHostInfo::localHostName(); - QString oldHostName = settings()->get("LastHostname").toString(); - if (currentHostName != oldHostName) - { - settings()->set("LastHostname", currentHostName); - return true; - } - QString currentJavaPath = settings()->get("JavaPath").toString(); - QString actualPath = FS::ResolveExecutable(currentJavaPath); - if (actualPath.isNull()) - { - return true; - } - return false; - }(); - bool analyticsRequired = [&]() - { - if(BuildConfig.ANALYTICS_ID.isEmpty()) - { - return false; - } - if (!settings()->get("Analytics").toBool()) - { - return false; - } - if (settings()->get("AnalyticsSeen").toInt() < analytics()->version()) - { - return true; - } - return false; - }(); - bool languageRequired = [&]() - { - if (settings()->get("Language").toString().isEmpty()) - return true; - return false; - }(); - bool wizardRequired = javaRequired || analyticsRequired || languageRequired; - - if(wizardRequired) - { - m_setupWizard = new SetupWizard(nullptr); - if (languageRequired) - { - m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard)); - } - if (javaRequired) - { - m_setupWizard->addPage(new JavaWizardPage(m_setupWizard)); - } - if(analyticsRequired) - { - m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard)); - } - connect(m_setupWizard, &QDialog::finished, this, &MultiMC::setupWizardFinished); - m_setupWizard->show(); - return true; - } - return false; -} - -void MultiMC::setupWizardFinished(int status) -{ - qDebug() << "Wizard result =" << status; - performMainStartupAction(); -} - -void MultiMC::performMainStartupAction() -{ - m_status = MultiMC::Initialized; - if(!m_instanceIdToLaunch.isEmpty()) - { - auto inst = instances()->getInstanceById(m_instanceIdToLaunch); - if(inst) - { - MinecraftServerTargetPtr serverToJoin = nullptr; - - if(!m_serverToJoin.isEmpty()) - { - serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin))); - qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching with server" << m_serverToJoin; - } - else - { - qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching"; - } - - launch(inst, true, nullptr, serverToJoin); - return; - } - } - if(!m_mainWindow) - { - // normal main window - showMainWindow(false); - qDebug() << "<> Main window shown."; - } - if(!m_zipToImport.isEmpty()) - { - qDebug() << "<> Importing instance from zip:" << m_zipToImport; - m_mainWindow->droppedURLs({ m_zipToImport }); - } -} - -void MultiMC::showFatalErrorMessage(const QString& title, const QString& content) -{ - m_status = MultiMC::Failed; - auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical); - dialog->exec(); -} - -MultiMC::~MultiMC() -{ - // kill the other globals. - Env::dispose(); - - // Shut down logger by setting the logger function to nothing - qInstallMessageHandler(nullptr); - -#if defined Q_OS_WIN32 - // Detach from Windows console - if(consoleAttached) - { - fclose(stdout); - fclose(stdin); - fclose(stderr); - FreeConsole(); - } -#endif -} - -void MultiMC::messageReceived(const QString& message) -{ - if(status() != Initialized) - { - qDebug() << "Received message" << message << "while still initializing. It will be ignored."; - return; - } - - QString command = message.section(' ', 0, 0); - - if(command == "activate") - { - showMainWindow(); - } - else if(command == "import") - { - QString arg = message.section(' ', 1); - if(arg.isEmpty()) - { - qWarning() << "Received" << command << "message without a zip path/URL."; - return; - } - m_mainWindow->droppedURLs({ QUrl(arg) }); - } - else if(command == "launch") - { - QString arg = message.section(' ', 1); - if(arg.isEmpty()) - { - qWarning() << "Received" << command << "message without an instance ID."; - return; - } - auto inst = instances()->getInstanceById(arg); - if(inst) - { - launch(inst, true, nullptr); - } - } - else if(command == "launch-with-server") - { - QString instanceID = message.section(' ', 1, 1); - QString serverToJoin = message.section(' ', 2, 2); - if(instanceID.isEmpty()) - { - qWarning() << "Received" << command << "message without an instance ID."; - return; - } - if(serverToJoin.isEmpty()) - { - qWarning() << "Received" << command << "message without a server to join."; - return; - } - auto inst = instances()->getInstanceById(instanceID); - if(inst) - { - launch( - inst, - true, - nullptr, - std::make_shared(MinecraftServerTarget::parse(serverToJoin)) - ); - } - } - else - { - qWarning() << "Received invalid message" << message; - } -} - -void MultiMC::analyticsSettingChanged(const Setting&, QVariant value) -{ - if(!m_analytics) - return; - bool enabled = value.toBool(); - if(enabled) - { - qDebug() << "Analytics enabled by user."; - } - else - { - qDebug() << "Analytics disabled by user."; - } - m_analytics->enable(enabled); -} - -std::shared_ptr MultiMC::translations() -{ - return m_translations; -} - -std::shared_ptr MultiMC::javalist() -{ - if (!m_javalist) - { - m_javalist.reset(new JavaInstallList()); - } - return m_javalist; -} - -std::vector MultiMC::getValidApplicationThemes() -{ - std::vector ret; - auto iter = m_themes.cbegin(); - while (iter != m_themes.cend()) - { - ret.push_back((*iter).second.get()); - iter++; - } - return ret; -} - -void MultiMC::setApplicationTheme(const QString& name, bool initial) -{ - auto systemPalette = qApp->palette(); - auto themeIter = m_themes.find(name); - if(themeIter != m_themes.end()) - { - auto & theme = (*themeIter).second; - theme->apply(initial); - } - else - { - qWarning() << "Tried to set invalid theme:" << name; - } -} - -void MultiMC::setIconTheme(const QString& name) -{ - XdgIcon::setThemeName(name); -} - -QIcon MultiMC::getThemedIcon(const QString& name) -{ - return XdgIcon::fromTheme(name); -} - -bool MultiMC::openJsonEditor(const QString &filename) -{ - const QString file = QDir::current().absoluteFilePath(filename); - if (m_settings->get("JsonEditor").toString().isEmpty()) - { - return DesktopServices::openUrl(QUrl::fromLocalFile(file)); - } - else - { - //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file); - return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file}); - } -} - -bool MultiMC::launch( - InstancePtr instance, - bool online, - BaseProfilerFactory *profiler, - MinecraftServerTargetPtr serverToJoin -) { - if(m_updateRunning) - { - qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; - } - else if(instance->canLaunch()) - { - auto & extras = m_instanceExtras[instance->id()]; - auto & window = extras.window; - if(window) - { - if(!window->saveAll()) - { - return false; - } - } - auto & controller = extras.controller; - controller.reset(new LaunchController()); - controller->setInstance(instance); - controller->setOnline(online); - controller->setProfiler(profiler); - controller->setServerToJoin(serverToJoin); - if(window) - { - controller->setParentWidget(window); - } - else if(m_mainWindow) - { - controller->setParentWidget(m_mainWindow); - } - connect(controller.get(), &LaunchController::succeeded, this, &MultiMC::controllerSucceeded); - connect(controller.get(), &LaunchController::failed, this, &MultiMC::controllerFailed); - addRunningInstance(); - controller->start(); - return true; - } - else if (instance->isRunning()) - { - showInstanceWindow(instance, "console"); - return true; - } - else if (instance->canEdit()) - { - showInstanceWindow(instance); - return true; - } - return false; -} - -bool MultiMC::kill(InstancePtr instance) -{ - if (!instance->isRunning()) - { - qWarning() << "Attempted to kill instance" << instance->id() << ", which isn't running."; - return false; - } - auto & extras = m_instanceExtras[instance->id()]; - // NOTE: copy of the shared pointer keeps it alive - auto controller = extras.controller; - if(controller) - { - return controller->abort(); - } - return true; -} - -void MultiMC::addRunningInstance() -{ - m_runningInstances ++; - if(m_runningInstances == 1) - { - emit updateAllowedChanged(false); - } -} - -void MultiMC::subRunningInstance() -{ - if(m_runningInstances == 0) - { - qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF"; - return; - } - m_runningInstances --; - if(m_runningInstances == 0) - { - emit updateAllowedChanged(true); - } -} - -bool MultiMC::shouldExitNow() const -{ - return m_runningInstances == 0 && m_openWindows == 0; -} - -bool MultiMC::updatesAreAllowed() -{ - return m_runningInstances == 0; -} - -void MultiMC::updateIsRunning(bool running) -{ - m_updateRunning = running; -} - - -void MultiMC::controllerSucceeded() -{ - auto controller = qobject_cast(QObject::sender()); - if(!controller) - return; - auto id = controller->id(); - auto & extras = m_instanceExtras[id]; - - // on success, do... - if (controller->instance()->settings()->get("AutoCloseConsole").toBool()) - { - if(extras.window) - { - extras.window->close(); - } - } - extras.controller.reset(); - subRunningInstance(); - - // quit when there are no more windows. - if(shouldExitNow()) - { - m_status = Status::Succeeded; - exit(0); - } -} - -void MultiMC::controllerFailed(const QString& error) -{ - Q_UNUSED(error); - auto controller = qobject_cast(QObject::sender()); - if(!controller) - return; - auto id = controller->id(); - auto & extras = m_instanceExtras[id]; - - // on failure, do... nothing - extras.controller.reset(); - subRunningInstance(); - - // quit when there are no more windows. - if(shouldExitNow()) - { - m_status = Status::Failed; - exit(1); - } -} - -void MultiMC::ShowGlobalSettings(class QWidget* parent, QString open_page) -{ - if(!m_globalSettingsProvider) { - return; - } - emit globalSettingsAboutToOpen(); - { - SettingsObject::Lock lock(MMC->settings()); - PageDialog dlg(m_globalSettingsProvider.get(), open_page, parent); - dlg.exec(); - } - emit globalSettingsClosed(); -} - -MainWindow* MultiMC::showMainWindow(bool minimized) -{ - if(m_mainWindow) - { - m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized); - m_mainWindow->raise(); - m_mainWindow->activateWindow(); - } - else - { - m_mainWindow = new MainWindow(); - m_mainWindow->restoreState(QByteArray::fromBase64(MMC->settings()->get("MainWindowState").toByteArray())); - m_mainWindow->restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray())); - if(minimized) - { - m_mainWindow->showMinimized(); - } - else - { - m_mainWindow->show(); - } - - m_mainWindow->checkInstancePathForProblems(); - connect(this, &MultiMC::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged); - connect(m_mainWindow, &MainWindow::isClosing, this, &MultiMC::on_windowClose); - m_openWindows++; - } - // FIXME: move this somewhere else... - if(m_analytics) - { - auto windowSize = m_mainWindow->size(); - auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height()); - qDebug() << "Viewport size" << sizeString; - m_analytics->setViewportSize(sizeString); - /* - * cm1 = java min heap [MB] - * cm2 = java max heap [MB] - * cm3 = system RAM [MB] - * - * cd1 = java version - * cd2 = java architecture - * cd3 = system architecture - * cd4 = CPU architecture - */ - QVariantMap customValues; - int min = m_settings->get("MinMemAlloc").toInt(); - int max = m_settings->get("MaxMemAlloc").toInt(); - if(min < max) - { - customValues["cm1"] = min; - customValues["cm2"] = max; - } - else - { - customValues["cm1"] = max; - customValues["cm2"] = min; - } - - constexpr uint64_t Mega = 1024ull * 1024ull; - int ramSize = int(Sys::getSystemRam() / Mega); - qDebug() << "RAM size is" << ramSize << "MB"; - customValues["cm3"] = ramSize; - - customValues["cd1"] = m_settings->get("JavaVersion"); - customValues["cd2"] = m_settings->get("JavaArchitecture"); - customValues["cd3"] = Sys::isSystem64bit() ? "64":"32"; - customValues["cd4"] = Sys::isCPU64bit() ? "64":"32"; - auto kernelInfo = Sys::getKernelInfo(); - customValues["cd5"] = kernelInfo.kernelName; - customValues["cd6"] = kernelInfo.kernelVersion; - auto distInfo = Sys::getDistributionInfo(); - if(!distInfo.distributionName.isEmpty()) - { - customValues["cd7"] = distInfo.distributionName; - } - if(!distInfo.distributionVersion.isEmpty()) - { - customValues["cd8"] = distInfo.distributionVersion; - } - m_analytics->sendScreenView("Main Window", customValues); - } - return m_mainWindow; -} - -InstanceWindow *MultiMC::showInstanceWindow(InstancePtr instance, QString page) -{ - if(!instance) - return nullptr; - auto id = instance->id(); - auto & extras = m_instanceExtras[id]; - auto & window = extras.window; - - if(window) - { - window->raise(); - window->activateWindow(); - } - else - { - window = new InstanceWindow(instance); - m_openWindows ++; - connect(window, &InstanceWindow::isClosing, this, &MultiMC::on_windowClose); - } - if(!page.isEmpty()) - { - window->selectPage(page); - } - if(extras.controller) - { - extras.controller->setParentWidget(window); - } - return window; -} - -void MultiMC::on_windowClose() -{ - m_openWindows--; - auto instWindow = qobject_cast(QObject::sender()); - if(instWindow) - { - auto & extras = m_instanceExtras[instWindow->instanceId()]; - extras.window = nullptr; - if(extras.controller) - { - extras.controller->setParentWidget(m_mainWindow); - } - } - auto mainWindow = qobject_cast(QObject::sender()); - if(mainWindow) - { - m_mainWindow = nullptr; - } - // quit when there are no more windows. - if(shouldExitNow()) - { - exit(0); - } -} diff --git a/launcher/MultiMC.h b/launcher/MultiMC.h deleted file mode 100644 index 59fd7345..00000000 --- a/launcher/MultiMC.h +++ /dev/null @@ -1,235 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "minecraft/launch/MinecraftServerTarget.h" - -class LaunchController; -class LocalPeer; -class InstanceWindow; -class MainWindow; -class SetupWizard; -class FolderInstanceProvider; -class GenericPageProvider; -class QFile; -class HttpMetaCache; -class SettingsObject; -class InstanceList; -class AccountList; -class IconList; -class QNetworkAccessManager; -class JavaInstallList; -class UpdateChecker; -class BaseProfilerFactory; -class BaseDetachedToolFactory; -class TranslationsModel; -class ITheme; -class MCEditTool; -class GAnalytics; - -#if defined(MMC) -#undef MMC -#endif -#define MMC (static_cast(QCoreApplication::instance())) - -class MultiMC : public QApplication -{ - // friends for the purpose of limiting access to deprecated stuff - Q_OBJECT -public: - enum Status - { - StartingUp, - Failed, - Succeeded, - Initialized - }; - -public: - MultiMC(int &argc, char **argv); - virtual ~MultiMC(); - - GAnalytics *analytics() const - { - return m_analytics; - } - - std::shared_ptr settings() const - { - return m_settings; - } - - qint64 timeSinceStart() const - { - return startTime.msecsTo(QDateTime::currentDateTime()); - } - - QIcon getThemedIcon(const QString& name); - - void setIconTheme(const QString& name); - - std::vector getValidApplicationThemes(); - - void setApplicationTheme(const QString& name, bool initial); - - // DownloadUpdateTask - std::shared_ptr updateChecker() - { - return m_updateChecker; - } - - std::shared_ptr translations(); - - std::shared_ptr javalist(); - - std::shared_ptr instances() const - { - return m_instances; - } - - FolderInstanceProvider * folderProvider() const - { - return m_instanceFolder; - } - - std::shared_ptr icons() const - { - return m_icons; - } - - MCEditTool *mcedit() const - { - return m_mcedit.get(); - } - - std::shared_ptr accounts() const - { - return m_accounts; - } - - Status status() const - { - return m_status; - } - - const QMap> &profilers() const - { - return m_profilers; - } - - /// this is the root of the 'installation'. Used for automatic updates - const QString &root() - { - return m_rootPath; - } - - /*! - * Opens a json file using either a system default editor, or, if not empty, the editor - * specified in the settings - */ - bool openJsonEditor(const QString &filename); - - InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString()); - MainWindow *showMainWindow(bool minimized = false); - - void updateIsRunning(bool running); - bool updatesAreAllowed(); - - void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); - -signals: - void updateAllowedChanged(bool status); - void globalSettingsAboutToOpen(); - void globalSettingsClosed(); - -public slots: - bool launch( - InstancePtr instance, - bool online = true, - BaseProfilerFactory *profiler = nullptr, - MinecraftServerTargetPtr serverToJoin = nullptr - ); - bool kill(InstancePtr instance); - -private slots: - void on_windowClose(); - void messageReceived(const QString & message); - void controllerSucceeded(); - void controllerFailed(const QString & error); - void analyticsSettingChanged(const Setting &setting, QVariant value); - void setupWizardFinished(int status); - -private: - bool createSetupWizard(); - void performMainStartupAction(); - - // sets the fatal error message and m_status to Failed. - void showFatalErrorMessage(const QString & title, const QString & content); - -private: - void addRunningInstance(); - void subRunningInstance(); - bool shouldExitNow() const; - -private: - QDateTime startTime; - - std::shared_ptr m_settings; - std::shared_ptr m_instances; - FolderInstanceProvider * m_instanceFolder = nullptr; - std::shared_ptr m_icons; - std::shared_ptr m_updateChecker; - std::shared_ptr m_accounts; - std::shared_ptr m_javalist; - std::shared_ptr m_translations; - std::shared_ptr m_globalSettingsProvider; - std::map> m_themes; - std::unique_ptr m_mcedit; - - QMap> m_profilers; - - QString m_rootPath; - Status m_status = MultiMC::StartingUp; - -#if defined Q_OS_WIN32 - // used on Windows to attach the standard IO streams - bool consoleAttached = false; -#endif - - // FIXME: attach to instances instead. - struct InstanceXtras - { - InstanceWindow * window = nullptr; - shared_qobject_ptr controller; - }; - std::map m_instanceExtras; - - // main state variables - size_t m_openWindows = 0; - size_t m_runningInstances = 0; - bool m_updateRunning = false; - - // main window, if any - MainWindow * m_mainWindow = nullptr; - - // peer MultiMC instance connector - used to implement single instance MultiMC and signalling - LocalPeer * m_peerInstance = nullptr; - - GAnalytics * m_analytics = nullptr; - SetupWizard * m_setupWizard = nullptr; -public: - QString m_instanceIdToLaunch; - QString m_serverToJoin; - bool m_liveCheck = false; - QUrl m_zipToImport; - std::unique_ptr logFile; -}; diff --git a/launcher/VersionProxyModel.cpp b/launcher/VersionProxyModel.cpp index 5587136f..12f9bdd8 100644 --- a/launcher/VersionProxyModel.cpp +++ b/launcher/VersionProxyModel.cpp @@ -1,5 +1,5 @@ #include "VersionProxyModel.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include #include @@ -194,19 +194,19 @@ QVariant VersionProxyModel::data(const QModelIndex &index, int role) const auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole); if(value.toBool()) { - return MMC->getThemedIcon("star"); + return LAUNCHER->getThemedIcon("star"); } else if(hasLatest) { auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole); if(value.toBool()) { - return MMC->getThemedIcon("bug"); + return LAUNCHER->getThemedIcon("bug"); } } else if(index.row() == 0) { - return MMC->getThemedIcon("bug"); + return LAUNCHER->getThemedIcon("bug"); } auto pixmap = QPixmapCache::find("placeholder"); if(!pixmap) diff --git a/launcher/dialogs/AboutDialog.cpp b/launcher/dialogs/AboutDialog.cpp index c97c471e..890f9f80 100644 --- a/launcher/dialogs/AboutDialog.cpp +++ b/launcher/dialogs/AboutDialog.cpp @@ -16,7 +16,7 @@ #include "AboutDialog.h" #include "ui_AboutDialog.h" #include -#include "MultiMC.h" +#include "Launcher.h" #include "BuildConfig.h" #include @@ -83,7 +83,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->urlLabel->setOpenExternalLinks(true); - ui->icon->setPixmap(MMC->getThemedIcon("logo").pixmap(64)); + ui->icon->setPixmap(LAUNCHER->getThemedIcon("logo").pixmap(64)); ui->title->setText("MultiMC 5"); ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); diff --git a/launcher/dialogs/CopyInstanceDialog.cpp b/launcher/dialogs/CopyInstanceDialog.cpp index 5fe90334..802016d9 100644 --- a/launcher/dialogs/CopyInstanceDialog.cpp +++ b/launcher/dialogs/CopyInstanceDialog.cpp @@ -16,7 +16,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "CopyInstanceDialog.h" #include "ui_CopyInstanceDialog.h" @@ -36,16 +36,16 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) layout()->setSizeConstraint(QLayout::SetFixedSize); InstIconKey = original->iconKey(); - ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); ui->instNameTextBox->setText(original->name()); ui->instNameTextBox->setFocus(); - auto groups = MMC->instances()->getGroups().toSet(); + auto groups = LAUNCHER->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(MMC->instances()->getInstanceGroup(m_original->id())); + int index = groupList.indexOf(LAUNCHER->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(MMC->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); } } diff --git a/launcher/dialogs/ExportInstanceDialog.cpp b/launcher/dialogs/ExportInstanceDialog.cpp index a42779d4..639b7043 100644 --- a/launcher/dialogs/ExportInstanceDialog.cpp +++ b/launcher/dialogs/ExportInstanceDialog.cpp @@ -27,7 +27,7 @@ #include #include "MMCStrings.h" #include "SeparatorPrefixTree.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -341,7 +341,7 @@ ExportInstanceDialog::~ExportInstanceDialog() void SaveIcon(InstancePtr m_instance) { auto iconKey = m_instance->iconKey(); - auto iconList = MMC->icons(); + auto iconList = LAUNCHER->icons(); auto mmcIcon = iconList->icon(iconKey); if(!mmcIcon || mmcIcon->isBuiltIn()) { return; diff --git a/launcher/dialogs/IconPickerDialog.cpp b/launcher/dialogs/IconPickerDialog.cpp index 90436554..3878d8e3 100644 --- a/launcher/dialogs/IconPickerDialog.cpp +++ b/launcher/dialogs/IconPickerDialog.cpp @@ -17,7 +17,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "IconPickerDialog.h" #include "ui_IconPickerDialog.h" @@ -59,7 +59,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) contentsWidget->installEventFilter(this); - contentsWidget->setModel(MMC->icons().get()); + contentsWidget->setModel(LAUNCHER->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)); - MMC->icons()->installIcons(fileNames); + LAUNCHER->icons()->installIcons(fileNames); } void IconPickerDialog::removeSelectedIcon() { - MMC->icons()->deleteIcon(selectedIconKey); + LAUNCHER->icons()->deleteIcon(selectedIconKey); } void IconPickerDialog::activated(QModelIndex index) @@ -132,7 +132,7 @@ void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection int IconPickerDialog::execWithSelection(QString selection) { - auto list = MMC->icons(); + auto list = LAUNCHER->icons(); auto contentsWidget = ui->iconView; selectedIconKey = selection; @@ -159,5 +159,5 @@ IconPickerDialog::~IconPickerDialog() void IconPickerDialog::openFolder() { - DesktopServices::openDirectory(MMC->icons()->getDirectory(), true); + DesktopServices::openDirectory(LAUNCHER->icons()->getDirectory(), true); } diff --git a/launcher/dialogs/NewComponentDialog.cpp b/launcher/dialogs/NewComponentDialog.cpp index f4d6274f..1cea54f4 100644 --- a/launcher/dialogs/NewComponentDialog.cpp +++ b/launcher/dialogs/NewComponentDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "Launcher.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 = MMC->instances()->getGroups().toSet(); + auto groups = LAUNCHER->instances()->getGroups().toSet(); ui->nameTextBox->setFocus(); originalPlaceholderText = ui->uidTextBox->placeholderText(); diff --git a/launcher/dialogs/NewInstanceDialog.cpp b/launcher/dialogs/NewInstanceDialog.cpp index 86963149..d18eb3d5 100644 --- a/launcher/dialogs/NewInstanceDialog.cpp +++ b/launcher/dialogs/NewInstanceDialog.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "Launcher.h" #include "NewInstanceDialog.h" #include "ui_NewInstanceDialog.h" @@ -48,12 +48,12 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString { ui->setupUi(this); - setWindowIcon(MMC->getThemedIcon("new")); + setWindowIcon(LAUNCHER->getThemedIcon("new")); InstIconKey = "default"; - ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); - auto groups = MMC->instances()->getGroups().toSet(); + auto groups = LAUNCHER->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(MMC->settings()->get("NewInstanceGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("NewInstanceGeometry").toByteArray())); } void NewInstanceDialog::reject() { - MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); QDialog::reject(); } void NewInstanceDialog::accept() { - MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + LAUNCHER->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(MMC->icons()->getIcon("default")); + ui->iconButton->setIcon(LAUNCHER->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 = MMC->icons()->getIcon(key); + auto icon = LAUNCHER->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(MMC->icons()->getIcon(InstIconKey)); + ui->iconButton->setIcon(LAUNCHER->icons()->getIcon(InstIconKey)); importIcon = false; } } @@ -247,9 +247,9 @@ void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) void NewInstanceDialog::importIconNow() { if(importIcon) { - MMC->icons()->installIcon(importIconPath, importIconName); + LAUNCHER->icons()->installIcon(importIconPath, importIconName); InstIconKey = importIconName; importIcon = false; } - MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); } diff --git a/launcher/dialogs/ProfileSelectDialog.cpp b/launcher/dialogs/ProfileSelectDialog.cpp index e2ad73e4..1082748f 100644 --- a/launcher/dialogs/ProfileSelectDialog.cpp +++ b/launcher/dialogs/ProfileSelectDialog.cpp @@ -23,14 +23,14 @@ #include -#include +#include ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent) : QDialog(parent), ui(new Ui::ProfileSelectDialog) { ui->setupUi(this); - m_accounts = MMC->accounts(); + m_accounts = LAUNCHER->accounts(); auto view = ui->listView; //view->setModel(m_accounts.get()); //view->hideColumn(AccountList::ActiveColumn); diff --git a/launcher/dialogs/UpdateDialog.cpp b/launcher/dialogs/UpdateDialog.cpp index 2baaf5e9..04732d1b 100644 --- a/launcher/dialogs/UpdateDialog.cpp +++ b/launcher/dialogs/UpdateDialog.cpp @@ -1,7 +1,7 @@ #include "UpdateDialog.h" #include "ui_UpdateDialog.h" #include -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -11,7 +11,7 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) { ui->setupUi(this); - auto channel = MMC->settings()->get("UpdateChannel").toString(); + auto channel = LAUNCHER->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("

Loading changelog...

")); loadChangelog(); - restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("UpdateDialogGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("UpdateDialogGeometry").toByteArray())); } UpdateDialog::~UpdateDialog() @@ -33,7 +33,7 @@ UpdateDialog::~UpdateDialog() void UpdateDialog::loadChangelog() { - auto channel = MMC->settings()->get("UpdateChannel").toString(); + auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); dljob.reset(new NetJob("Changelog")); QString url; if(channel == "stable") @@ -65,7 +65,7 @@ QString reprocessMarkdown(QByteArray markdown) QString reprocessCommits(QByteArray json) { - auto channel = MMC->settings()->get("UpdateChannel").toString(); + auto channel = LAUNCHER->settings()->get("UpdateChannel").toString(); try { QString result; @@ -177,6 +177,6 @@ void UpdateDialog::on_btnUpdateNow_clicked() void UpdateDialog::closeEvent(QCloseEvent* evt) { - MMC->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); QDialog::closeEvent(evt); } diff --git a/launcher/dialogs/VersionSelectDialog.cpp b/launcher/dialogs/VersionSelectDialog.cpp index ed1210ba..82eb70f4 100644 --- a/launcher/dialogs/VersionSelectDialog.cpp +++ b/launcher/dialogs/VersionSelectDialog.cpp @@ -28,7 +28,7 @@ #include #include #include -#include "MultiMC.h" +#include "Launcher.h" #include #include diff --git a/launcher/main.cpp b/launcher/main.cpp index b0360c7e..e32f6b4b 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -1,4 +1,4 @@ -#include "MultiMC.h" +#include "Launcher.h" #include "MainWindow.h" #include "LaunchController.h" #include @@ -34,12 +34,12 @@ int main(int argc, char *argv[]) #endif // initialize Qt - MultiMC app(argc, argv); + Launcher app(argc, argv); switch (app.status()) { - case MultiMC::StartingUp: - case MultiMC::Initialized: + case Launcher::StartingUp: + case Launcher::Initialized: { Q_INIT_RESOURCE(multimc); Q_INIT_RESOURCE(backgrounds); @@ -53,9 +53,9 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(flat); return app.exec(); } - case MultiMC::Failed: + case Launcher::Failed: return 1; - case MultiMC::Succeeded: + case Launcher::Succeeded: return 0; } } diff --git a/launcher/minecraft/OneSixVersionFormat.cpp b/launcher/minecraft/OneSixVersionFormat.cpp index 0329d70e..2572c39e 100644 --- a/launcher/minecraft/OneSixVersionFormat.cpp +++ b/launcher/minecraft/OneSixVersionFormat.cpp @@ -16,11 +16,11 @@ static void readString(const QJsonObject &root, const QString &key, QString &var LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, const QJsonObject &libObj, const QString &filename) { LibraryPtr out = MojangVersionFormat::libraryFromJson(problems, libObj, filename); - readString(libObj, "MMC-hint", out->m_hint); - readString(libObj, "MMC-absulute_url", out->m_absoluteURL); - readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL); - readString(libObj, "MMC-filename", out->m_filename); - readString(libObj, "MMC-displayname", out->m_displayname); + readString(libObj, "LAUNCHER-hint", out->m_hint); + readString(libObj, "LAUNCHER-absulute_url", out->m_absoluteURL); + readString(libObj, "LAUNCHER-absoluteUrl", out->m_absoluteURL); + readString(libObj, "LAUNCHER-filename", out->m_filename); + readString(libObj, "LAUNCHER-displayname", out->m_displayname); return out; } @@ -28,13 +28,13 @@ QJsonObject OneSixVersionFormat::libraryToJson(Library *library) { QJsonObject libRoot = MojangVersionFormat::libraryToJson(library); if (library->m_absoluteURL.size()) - libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL); + libRoot.insert("LAUNCHER-absoluteUrl", library->m_absoluteURL); if (library->m_hint.size()) - libRoot.insert("MMC-hint", library->m_hint); + libRoot.insert("LAUNCHER-hint", library->m_hint); if (library->m_filename.size()) - libRoot.insert("MMC-filename", library->m_filename); + libRoot.insert("LAUNCHER-filename", library->m_filename); if (library->m_displayname.size()) - libRoot.insert("MMC-displayname", library->m_displayname); + libRoot.insert("LAUNCHER-displayname", library->m_displayname); return libRoot; } diff --git a/launcher/package/linux/MultiMC b/launcher/package/linux/MultiMC deleted file mode 100755 index be35e83c..00000000 --- a/launcher/package/linux/MultiMC +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash -# Basic start script for running MultiMC with the libs packaged with it. - -function printerror { - printf "$1" - if which zenity >/dev/null; then zenity --error --text="$1" &>/dev/null; - elif which kdialog >/dev/null; then kdialog --error "$1" &>/dev/null; - fi -} - -if [[ $EUID -eq 0 ]]; then - printerror "This program should not be run using sudo or as the root user!\n" - exit 1 -fi - - -MMC_DIR="$(dirname "$(readlink -f "$0")")" -echo "MultiMC Dir: ${MMC_DIR}" - -# Set up env - filter out input LD_ variables but pass them in under different names -export GAME_LIBRARY_PATH=${GAME_LIBRARY_PATH-${LD_LIBRARY_PATH}} -export GAME_PRELOAD=${GAME_PRELOAD-${LD_PRELOAD}} -export LD_LIBRARY_PATH="${MMC_DIR}/bin":$MMC_LIBRARY_PATH -export LD_PRELOAD=$MMC_PRELOAD -export QT_PLUGIN_PATH="${MMC_DIR}/plugins" -export QT_FONTPATH="${MMC_DIR}/fonts" - -# Detect missing dependencies... -DEPS_LIST=`ldd "${MMC_DIR}"/plugins/*/*.so 2>/dev/null | grep "not found" | sort -u | awk -vORS=", " '{ print $1 }'` -if [ "x$DEPS_LIST" = "x" ]; then - # We have all our dependencies. Run MultiMC. - echo "No missing dependencies found." - - # Just to be sure... - chmod +x "${MMC_DIR}/bin/MultiMC" - - # Run MultiMC - exec -a "${MMC_DIR}/MultiMC" "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@" - - # Run MultiMC in valgrind - # valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@" - - # Run MultiMC with callgrind, delay instrumentation - # valgrind --log-file="valgrind.log" --tool=callgrind --instr-atstart=no "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@" - # use callgrind_control -i on/off to profile actions - - # Exit with MultiMC's exit code. - # exit $? -else - # apt - if which apt-file &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do apt-file -l search $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo apt-get install $COMMAND_LIBS" - # pacman - elif which pkgfile &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pkgfile $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo pacman -S $COMMAND_LIBS" - # dnf - elif which dnf &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do dnf whatprovides -q $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | grep -v 'Repo' | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo dnf install $COMMAND_LIBS" - # yum - elif which yum &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do yum whatprovides $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo yum install $COMMAND_LIBS" - # zypper - elif which zypper &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do zypper wp $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo zypper install $COMMAND_LIBS" - # emerge - elif which pfl &>/dev/null; then - LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u` - COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pfl $LIBRARY; done` - COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'` - INSTALL_CMD="sudo emerge $COMMAND_LIBS" - fi - - MESSAGE="Error: MultiMC is missing the following libraries that it needs to work correctly:\n\t${DEPS_LIST}\nPlease install them from your distribution's package manager." - MESSAGE="$MESSAGE\n\nHint (please apply common sense): $INSTALL_CMD\n" - - printerror "$MESSAGE" - exit 1 -fi diff --git a/launcher/package/linux/multimc.desktop b/launcher/package/linux/multimc.desktop deleted file mode 100755 index c25be047..00000000 --- a/launcher/package/linux/multimc.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -Version=1.0 -Name=MultiMC -GenericName=Minecraft Launcher -Comment=Free, open source launcher and instance manager for Minecraft. -Type=Application -Terminal=false -Exec=multimc -Icon=multimc -Categories=Game -Keywords=game;minecraft; diff --git a/launcher/pagedialog/PageDialog.cpp b/launcher/pagedialog/PageDialog.cpp index fd5d36d4..79d7acd3 100644 --- a/launcher/pagedialog/PageDialog.cpp +++ b/launcher/pagedialog/PageDialog.cpp @@ -20,7 +20,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "settings/SettingsObject.h" #include "widgets/IconLabel.h" #include "widgets/PageContainer.h" @@ -45,7 +45,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(MMC->settings()->get("PagedGeometry").toByteArray())); + restoreGeometry(QByteArray::fromBase64(LAUNCHER->settings()->get("PagedGeometry").toByteArray())); } void PageDialog::closeEvent(QCloseEvent *event) @@ -54,7 +54,7 @@ void PageDialog::closeEvent(QCloseEvent *event) if (m_container->prepareToClose()) { qDebug() << "Paged dialog close approved"; - MMC->settings()->set("PagedGeometry", saveGeometry().toBase64()); + LAUNCHER->settings()->set("PagedGeometry", saveGeometry().toBase64()); qDebug() << "Paged dialog geometry saved"; QDialog::closeEvent(event); } diff --git a/launcher/pages/global/AccountListPage.cpp b/launcher/pages/global/AccountListPage.cpp index 74537712..4f8b8e9c 100644 --- a/launcher/pages/global/AccountListPage.cpp +++ b/launcher/pages/global/AccountListPage.cpp @@ -32,7 +32,7 @@ #include "minecraft/auth/AccountTask.h" #include "minecraft/services/SkinDelete.h" -#include "MultiMC.h" +#include "Launcher.h" #include "BuildConfig.h" #include @@ -50,7 +50,7 @@ AccountListPage::AccountListPage(QWidget *parent) ui->listView->setEmptyMode(VersionListView::String); ui->listView->setContextMenuPolicy(Qt::CustomContextMenu); - m_accounts = MMC->accounts(); + m_accounts = LAUNCHER->accounts(); ui->listView->setModel(m_accounts.get()); ui->listView->header()->setSectionResizeMode(0, QHeaderView::Stretch); diff --git a/launcher/pages/global/AccountListPage.h b/launcher/pages/global/AccountListPage.h index 4474802e..ee81acd1 100644 --- a/launcher/pages/global/AccountListPage.h +++ b/launcher/pages/global/AccountListPage.h @@ -21,7 +21,7 @@ #include "pages/BasePage.h" #include "minecraft/auth/AccountList.h" -#include "MultiMC.h" +#include "Launcher.h" namespace Ui { @@ -43,10 +43,10 @@ public: } QIcon icon() const override { - auto icon = MMC->getThemedIcon("accounts"); + auto icon = LAUNCHER->getThemedIcon("accounts"); if(icon.isNull()) { - icon = MMC->getThemedIcon("noaccount"); + icon = LAUNCHER->getThemedIcon("noaccount"); } return icon; } diff --git a/launcher/pages/global/CustomCommandsPage.cpp b/launcher/pages/global/CustomCommandsPage.cpp index 3b182319..8a5c3445 100644 --- a/launcher/pages/global/CustomCommandsPage.cpp +++ b/launcher/pages/global/CustomCommandsPage.cpp @@ -32,7 +32,7 @@ bool CustomCommandsPage::apply() void CustomCommandsPage::applySettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->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 = MMC->settings(); + auto s = LAUNCHER->settings(); commands->initialize( false, true, diff --git a/launcher/pages/global/CustomCommandsPage.h b/launcher/pages/global/CustomCommandsPage.h index 414c3259..ac69a997 100644 --- a/launcher/pages/global/CustomCommandsPage.h +++ b/launcher/pages/global/CustomCommandsPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "widgets/CustomCommands.h" class CustomCommandsPage : public QWidget, public BasePage @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("custom-commands"); + return LAUNCHER->getThemedIcon("custom-commands"); } QString id() const override { diff --git a/launcher/pages/global/ExternalToolsPage.cpp b/launcher/pages/global/ExternalToolsPage.cpp index 6a0a38be..7e1a915f 100644 --- a/launcher/pages/global/ExternalToolsPage.cpp +++ b/launcher/pages/global/ExternalToolsPage.cpp @@ -24,7 +24,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" #include -#include "MultiMC.h" +#include "Launcher.h" #include ExternalToolsPage::ExternalToolsPage(QWidget *parent) : @@ -51,7 +51,7 @@ ExternalToolsPage::~ExternalToolsPage() void ExternalToolsPage::loadSettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->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 = MMC->settings(); + auto s = LAUNCHER->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 (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error)) + if (!LAUNCHER->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 (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) + if (!LAUNCHER->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 (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error)) + if (!LAUNCHER->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 (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) + if (!LAUNCHER->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 (!MMC->mcedit()->check(cooked_dir, error)) + if (!LAUNCHER->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 (!MMC->mcedit()->check(ui->mceditPathEdit->text(), error)) + if (!LAUNCHER->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/pages/global/ExternalToolsPage.h index 0fc8ebe1..1d99273a 100644 --- a/launcher/pages/global/ExternalToolsPage.h +++ b/launcher/pages/global/ExternalToolsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { class ExternalToolsPage; @@ -38,10 +38,10 @@ public: } QIcon icon() const override { - auto icon = MMC->getThemedIcon("externaltools"); + auto icon = LAUNCHER->getThemedIcon("externaltools"); if(icon.isNull()) { - icon = MMC->getThemedIcon("loadermods"); + icon = LAUNCHER->getThemedIcon("loadermods"); } return icon; } diff --git a/launcher/pages/global/JavaPage.cpp b/launcher/pages/global/JavaPage.cpp index cde0e035..dd158fcd 100644 --- a/launcher/pages/global/JavaPage.cpp +++ b/launcher/pages/global/JavaPage.cpp @@ -29,7 +29,7 @@ #include "settings/SettingsObject.h" #include -#include "MultiMC.h" +#include "Launcher.h" #include JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage) @@ -55,7 +55,7 @@ bool JavaPage::apply() void JavaPage::applySettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Memory int min = ui->minMemSpinBox->value(); @@ -79,7 +79,7 @@ void JavaPage::applySettings() } void JavaPage::loadSettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->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(MMC->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/global/JavaPage.h b/launcher/pages/global/JavaPage.h index 832f460b..93a586cd 100644 --- a/launcher/pages/global/JavaPage.h +++ b/launcher/pages/global/JavaPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" #include "JavaCommon.h" -#include +#include #include class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("java"); + return LAUNCHER->getThemedIcon("java"); } QString id() const override { diff --git a/launcher/pages/global/LanguagePage.cpp b/launcher/pages/global/LanguagePage.cpp index ae3168cc..409bf7d0 100644 --- a/launcher/pages/global/LanguagePage.cpp +++ b/launcher/pages/global/LanguagePage.cpp @@ -26,7 +26,7 @@ bool LanguagePage::apply() void LanguagePage::applySettings() { - auto settings = MMC->settings(); + auto settings = LAUNCHER->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); } diff --git a/launcher/pages/global/LanguagePage.h b/launcher/pages/global/LanguagePage.h index ca8eecc6..22db8f94 100644 --- a/launcher/pages/global/LanguagePage.h +++ b/launcher/pages/global/LanguagePage.h @@ -17,7 +17,7 @@ #include #include "pages/BasePage.h" -#include +#include #include class LanguageSelectionWidget; @@ -36,7 +36,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("language"); + return LAUNCHER->getThemedIcon("language"); } QString id() const override { diff --git a/launcher/pages/global/LauncherPage.cpp b/launcher/pages/global/LauncherPage.cpp new file mode 100644 index 00000000..5f8d87d8 --- /dev/null +++ b/launcher/pages/global/LauncherPage.cpp @@ -0,0 +1,466 @@ +/* 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 "LauncherPage.h" +#include "ui_LauncherPage.h" + +#include +#include +#include +#include + +#include "updater/UpdateChecker.h" + +#include "settings/SettingsObject.h" +#include +#include "Launcher.h" +#include "BuildConfig.h" +#include "themes/ITheme.h" + +#include +#include + +// FIXME: possibly move elsewhere +enum InstSortMode +{ + // Sort alphabetically by name. + Sort_Name, + // Sort by which instance was launched most recently. + Sort_LastLaunch +}; + +LauncherPage::LauncherPage(QWidget *parent) : QWidget(parent), ui(new Ui::LauncherPage) +{ + ui->setupUi(this); + auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole()); + auto origBackground = ui->fontPreview->palette().color(ui->fontPreview->backgroundRole()); + m_colors.reset(new LogColorCache(origForeground, origBackground)); + + ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); + ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); + + defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); + + m_languageModel = LAUNCHER->translations(); + loadSettings(); + + if(BuildConfig.UPDATER_ENABLED) + { + QObject::connect(LAUNCHER->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &LauncherPage::refreshUpdateChannelList); + + if (LAUNCHER->updateChecker()->hasChannels()) + { + refreshUpdateChannelList(); + } + else + { + LAUNCHER->updateChecker()->updateChanList(false); + } + } + else + { + ui->updateSettingsBox->setHidden(true); + } + // Analytics + if(BuildConfig.ANALYTICS_ID.isEmpty()) + { + ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab)); + } + connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview())); + connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview())); + + //move mac data button + QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); + if (!file.exists()) + { + ui->migrateDataFolderMacBtn->setVisible(false); + } +} + +LauncherPage::~LauncherPage() +{ + delete ui; + delete defaultFormat; +} + +bool LauncherPage::apply() +{ + applySettings(); + return true; +} + +void LauncherPage::on_instDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text()); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) + { + QString cooked_dir = FS::NormalizePath(raw_dir); + if (FS::checkProblemticPathJava(QDir(cooked_dir))) + { + QMessageBox warning; + warning.setText(tr("You're trying to specify an instance folder which\'s path " + "contains at least one \'!\'. " + "Java is known to cause problems if that is the case, your " + "instances (probably) won't start!")); + warning.setInformativeText( + tr("Do you really want to use this path? " + "Selecting \"No\" will close this and not alter your instance path.")); + warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + int result = warning.exec(); + if (result == QMessageBox::Yes) + { + ui->instDirTextBox->setText(cooked_dir); + } + } + else + { + ui->instDirTextBox->setText(cooked_dir); + } + } +} + +void LauncherPage::on_iconsDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text()); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) + { + QString cooked_dir = FS::NormalizePath(raw_dir); + ui->iconsDirTextBox->setText(cooked_dir); + } +} +void LauncherPage::on_modsDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text()); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) + { + QString cooked_dir = FS::NormalizePath(raw_dir); + ui->modsDirTextBox->setText(cooked_dir); + } +} +void LauncherPage::on_migrateDataFolderMacBtn_clicked() +{ + QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); + file.remove(); + QProcess::startDetached(qApp->arguments()[0]); + qApp->quit(); +} + +void LauncherPage::refreshUpdateChannelList() +{ + // Stop listening for selection changes. It's going to change a lot while we update it and + // we don't need to update the + // description label constantly. + QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(updateChannelSelectionChanged(int))); + + QList channelList = LAUNCHER->updateChecker()->getChannelList(); + ui->updateChannelComboBox->clear(); + int selection = -1; + for (int i = 0; i < channelList.count(); i++) + { + UpdateChecker::ChannelListEntry entry = channelList.at(i); + + // When it comes to selection, we'll rely on the indexes of a channel entry being the + // same in the + // combo box as it is in the update checker's channel list. + // This probably isn't very safe, but the channel list doesn't change often enough (or + // at all) for + // this to be a big deal. Hope it doesn't break... + ui->updateChannelComboBox->addItem(entry.name); + + // If the update channel we just added was the selected one, set the current index in + // the combo box to it. + if (entry.id == m_currentUpdateChannel) + { + qDebug() << "Selected index" << i << "channel id" << m_currentUpdateChannel; + selection = i; + } + } + + ui->updateChannelComboBox->setCurrentIndex(selection); + + // Start listening for selection changes again and update the description label. + QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(updateChannelSelectionChanged(int))); + refreshUpdateChannelDesc(); + + // Now that we've updated the channel list, we can enable the combo box. + // It starts off disabled so that if the channel list hasn't been loaded, it will be + // disabled. + ui->updateChannelComboBox->setEnabled(true); +} + +void LauncherPage::updateChannelSelectionChanged(int index) +{ + refreshUpdateChannelDesc(); +} + +void LauncherPage::refreshUpdateChannelDesc() +{ + // Get the channel list. + QList channelList = LAUNCHER->updateChecker()->getChannelList(); + int selectedIndex = ui->updateChannelComboBox->currentIndex(); + if (selectedIndex < 0) + { + return; + } + if (selectedIndex < channelList.count()) + { + // Find the channel list entry with the given index. + UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex); + + // Set the description text. + ui->updateChannelDescLabel->setText(selected.description); + + // Set the currently selected channel ID. + m_currentUpdateChannel = selected.id; + } +} + +void LauncherPage::applySettings() +{ + auto s = LAUNCHER->settings(); + + if (ui->resetNotificationsBtn->isChecked()) + { + s->set("ShownNotifications", QString()); + } + + // Updates + s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); + s->set("UpdateChannel", m_currentUpdateChannel); + auto original = s->get("IconTheme").toString(); + //FIXME: make generic + switch (ui->themeComboBox->currentIndex()) + { + case 1: + s->set("IconTheme", "pe_dark"); + break; + case 2: + s->set("IconTheme", "pe_light"); + break; + case 3: + s->set("IconTheme", "pe_blue"); + break; + case 4: + s->set("IconTheme", "pe_colored"); + break; + case 5: + s->set("IconTheme", "OSX"); + break; + case 6: + s->set("IconTheme", "iOS"); + break; + case 7: + s->set("IconTheme", "flat"); + break; + case 8: + s->set("IconTheme", "custom"); + break; + case 0: + default: + s->set("IconTheme", "multimc"); + break; + } + + if(original != s->get("IconTheme")) + { + LAUNCHER->setIconTheme(s->get("IconTheme").toString()); + } + + auto originalAppTheme = s->get("ApplicationTheme").toString(); + auto newAppTheme = ui->themeComboBoxColors->currentData().toString(); + if(originalAppTheme != newAppTheme) + { + s->set("ApplicationTheme", newAppTheme); + LAUNCHER->setApplicationTheme(newAppTheme, false); + } + + // Console settings + s->set("ShowConsole", ui->showConsoleCheck->isChecked()); + s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); + s->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked()); + QString consoleFontFamily = ui->consoleFont->currentFont().family(); + s->set("ConsoleFont", consoleFontFamily); + s->set("ConsoleFontSize", ui->fontSizeBox->value()); + s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value()); + s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked); + + // Folders + // TODO: Offer to move instances to new instance folder. + s->set("InstanceDir", ui->instDirTextBox->text()); + s->set("CentralModsDir", ui->modsDirTextBox->text()); + s->set("IconsDir", ui->iconsDirTextBox->text()); + + auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); + switch (sortMode) + { + case Sort_LastLaunch: + s->set("InstSortMode", "LastLaunch"); + break; + case Sort_Name: + default: + s->set("InstSortMode", "Name"); + break; + } + + // Analytics + if(!BuildConfig.ANALYTICS_ID.isEmpty()) + { + s->set("Analytics", ui->analyticsCheck->isChecked()); + } +} +void LauncherPage::loadSettings() +{ + auto s = LAUNCHER->settings(); + // Updates + ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); + m_currentUpdateChannel = s->get("UpdateChannel").toString(); + //FIXME: make generic + auto theme = s->get("IconTheme").toString(); + if (theme == "pe_dark") + { + ui->themeComboBox->setCurrentIndex(1); + } + else if (theme == "pe_light") + { + ui->themeComboBox->setCurrentIndex(2); + } + else if (theme == "pe_blue") + { + ui->themeComboBox->setCurrentIndex(3); + } + else if (theme == "pe_colored") + { + ui->themeComboBox->setCurrentIndex(4); + } + else if (theme == "OSX") + { + ui->themeComboBox->setCurrentIndex(5); + } + else if (theme == "iOS") + { + ui->themeComboBox->setCurrentIndex(6); + } + else if (theme == "flat") + { + ui->themeComboBox->setCurrentIndex(7); + } + else if (theme == "custom") + { + ui->themeComboBox->setCurrentIndex(8); + } + else + { + ui->themeComboBox->setCurrentIndex(0); + } + + { + auto currentTheme = s->get("ApplicationTheme").toString(); + auto themes = LAUNCHER->getValidApplicationThemes(); + int idx = 0; + for(auto &theme: themes) + { + ui->themeComboBoxColors->addItem(theme->name(), theme->id()); + if(currentTheme == theme->id()) + { + ui->themeComboBoxColors->setCurrentIndex(idx); + } + idx++; + } + } + + // Console settings + 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(); + QFont consoleFont(fontFamily); + ui->consoleFont->setCurrentFont(consoleFont); + + bool conversionOk = true; + int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); + if(!conversionOk) + { + fontSize = 11; + } + ui->fontSizeBox->setValue(fontSize); + refreshFontPreview(); + ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt()); + ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool()); + + // Folders + ui->instDirTextBox->setText(s->get("InstanceDir").toString()); + ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); + ui->iconsDirTextBox->setText(s->get("IconsDir").toString()); + + QString sortMode = s->get("InstSortMode").toString(); + + if (sortMode == "LastLaunch") + { + ui->sortLastLaunchedBtn->setChecked(true); + } + else + { + ui->sortByNameBtn->setChecked(true); + } + + // Analytics + if(!BuildConfig.ANALYTICS_ID.isEmpty()) + { + ui->analyticsCheck->setChecked(s->get("Analytics").toBool()); + } +} + +void LauncherPage::refreshFontPreview() +{ + int fontSize = ui->fontSizeBox->value(); + QString fontFamily = ui->consoleFont->currentFont().family(); + ui->fontPreview->clear(); + defaultFormat->setFont(QFont(fontFamily, fontSize)); + { + QTextCharFormat format(*defaultFormat); + format.setForeground(m_colors->getFront(MessageLevel::Error)); + // append a paragraph/line + auto workCursor = ui->fontPreview->textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(tr("[Something/ERROR] A spooky error!"), format); + workCursor.insertBlock(); + } + { + QTextCharFormat format(*defaultFormat); + format.setForeground(m_colors->getFront(MessageLevel::Message)); + // append a paragraph/line + auto workCursor = ui->fontPreview->textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(tr("[Test/INFO] A harmless message..."), format); + workCursor.insertBlock(); + } + { + QTextCharFormat format(*defaultFormat); + format.setForeground(m_colors->getFront(MessageLevel::Warning)); + // append a paragraph/line + auto workCursor = ui->fontPreview->textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(tr("[Something/WARN] A not so spooky warning."), format); + workCursor.insertBlock(); + } +} diff --git a/launcher/pages/global/LauncherPage.h b/launcher/pages/global/LauncherPage.h new file mode 100644 index 00000000..d851bfcc --- /dev/null +++ b/launcher/pages/global/LauncherPage.h @@ -0,0 +1,103 @@ +/* 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 +#include + +#include "java/JavaChecker.h" +#include "pages/BasePage.h" +#include +#include "ColorCache.h" +#include + +class QTextCharFormat; +class SettingsObject; + +namespace Ui +{ +class LauncherPage; +} + +class LauncherPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit LauncherPage(QWidget *parent = 0); + ~LauncherPage(); + + QString displayName() const override + { + return "MultiMC"; + } + QIcon icon() const override + { + return LAUNCHER->getThemedIcon("multimc"); + } + QString id() const override + { + return "multimc-settings"; + } + QString helpPage() const override + { + return "MultiMC-settings"; + } + bool apply() override; + +private: + void applySettings(); + void loadSettings(); + +private +slots: + void on_instDirBrowseBtn_clicked(); + void on_modsDirBrowseBtn_clicked(); + void on_iconsDirBrowseBtn_clicked(); + void on_migrateDataFolderMacBtn_clicked(); + + /*! + * Updates the list of update channels in the combo box. + */ + void refreshUpdateChannelList(); + + /*! + * Updates the channel description label. + */ + void refreshUpdateChannelDesc(); + + /*! + * Updates the font preview + */ + void refreshFontPreview(); + + void updateChannelSelectionChanged(int index); + +private: + Ui::LauncherPage *ui; + + /*! + * Stores the currently selected update channel. + */ + QString m_currentUpdateChannel; + + // default format for the font preview... + QTextCharFormat *defaultFormat; + + std::unique_ptr m_colors; + + std::shared_ptr m_languageModel; +}; diff --git a/launcher/pages/global/LauncherPage.ui b/launcher/pages/global/LauncherPage.ui new file mode 100644 index 00000000..34fb9b57 --- /dev/null +++ b/launcher/pages/global/LauncherPage.ui @@ -0,0 +1,584 @@ + + + LauncherPage + + + + 0 + 0 + 514 + 629 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QTabWidget::Rounded + + + 0 + + + + Features + + + + + + Update Settings + + + + + + Check for updates when MultiMC starts? + + + + + + + Up&date Channel: + + + updateChannelComboBox + + + + + + + false + + + + + + + No channel selected. + + + true + + + + + + + + + + Folders + + + + + + I&nstances: + + + instDirTextBox + + + + + + + + + + ... + + + + + + + &Mods: + + + modsDirTextBox + + + + + + + + + + ... + + + + + + + + + + &Icons: + + + iconsDirTextBox + + + + + + + ... + + + + + + + + + + Move MultiMC data to new location (will restart MultiMC) + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + User Interface + + + + + + MultiMC notifications + + + + + + Reset hidden notifications + + + true + + + + + + + + + + true + + + Instance view sorting mode + + + + + + By &last launched + + + sortingModeGroup + + + + + + + By &name + + + sortingModeGroup + + + + + + + + + + Theme + + + + + + &Icons + + + themeComboBox + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + Default + + + + + Simple (Dark Icons) + + + + + Simple (Light Icons) + + + + + Simple (Blue Icons) + + + + + Simple (Colored Icons) + + + + + OSX + + + + + iOS + + + + + Flat + + + + + Custom + + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + Colors + + + themeComboBoxColors + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Console + + + + + + Console Settings + + + + + + Show console while the game is running? + + + + + + + Automatically close console when the game quits? + + + + + + + Show console when the game crashes? + + + + + + + + + + History limit + + + + + + Stop logging when log overflows + + + + + + + + 0 + 0 + + + + lines + + + 10000 + + + 1000000 + + + 10000 + + + 100000 + + + + + + + + + + + 0 + 0 + + + + Console font + + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOff + + + false + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + 0 + 0 + + + + + + + + 5 + + + 16 + + + 11 + + + + + + + + + + + Analytics + + + + + + Analytics Settings + + + + + + Send anonymous usage statistics? + + + + + + + Qt::Horizontal + + + + + + + <html><head/> +<body> +<p>MultiMC sends anonymous usage statistics on every start of the application.</p><p>The following data is collected:</p> +<ul> +<li>MultiMC version.</li> +<li>Operating system name, version and architecture.</li> +<li>CPU architecture (kernel architecture on linux).</li> +<li>Size of system memory.</li> +<li>Java version, architecture and memory settings.</li> +</ul> +</body></html> + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + tabWidget + autoUpdateCheckBox + updateChannelComboBox + instDirTextBox + instDirBrowseBtn + modsDirTextBox + modsDirBrowseBtn + iconsDirTextBox + iconsDirBrowseBtn + resetNotificationsBtn + sortLastLaunchedBtn + sortByNameBtn + themeComboBox + themeComboBoxColors + showConsoleCheck + autoCloseConsoleCheck + showConsoleErrorCheck + lineLimitSpinBox + checkStopLogging + consoleFont + fontSizeBox + fontPreview + + + + + + + diff --git a/launcher/pages/global/MinecraftPage.cpp b/launcher/pages/global/MinecraftPage.cpp index 6c9bd307..2830dc7c 100644 --- a/launcher/pages/global/MinecraftPage.cpp +++ b/launcher/pages/global/MinecraftPage.cpp @@ -21,7 +21,7 @@ #include #include "settings/SettingsObject.h" -#include "MultiMC.h" +#include "Launcher.h" MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage) { @@ -57,7 +57,7 @@ void MinecraftPage::on_maximizedCheckBox_clicked(bool checked) void MinecraftPage::applySettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Window Size s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); @@ -75,7 +75,7 @@ void MinecraftPage::applySettings() void MinecraftPage::loadSettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Window Size ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); diff --git a/launcher/pages/global/MinecraftPage.h b/launcher/pages/global/MinecraftPage.h index 5e781aed..0fc6cc8e 100644 --- a/launcher/pages/global/MinecraftPage.h +++ b/launcher/pages/global/MinecraftPage.h @@ -20,7 +20,7 @@ #include "java/JavaChecker.h" #include "pages/BasePage.h" -#include +#include class SettingsObject; @@ -43,7 +43,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("minecraft"); + return LAUNCHER->getThemedIcon("minecraft"); } QString id() const override { diff --git a/launcher/pages/global/MultiMCPage.cpp b/launcher/pages/global/MultiMCPage.cpp deleted file mode 100644 index 5d43b187..00000000 --- a/launcher/pages/global/MultiMCPage.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/* 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 "MultiMCPage.h" -#include "ui_MultiMCPage.h" - -#include -#include -#include -#include - -#include "updater/UpdateChecker.h" - -#include "settings/SettingsObject.h" -#include -#include "MultiMC.h" -#include "BuildConfig.h" -#include "themes/ITheme.h" - -#include -#include - -// FIXME: possibly move elsewhere -enum InstSortMode -{ - // Sort alphabetically by name. - Sort_Name, - // Sort by which instance was launched most recently. - Sort_LastLaunch -}; - -MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCPage) -{ - ui->setupUi(this); - auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole()); - auto origBackground = ui->fontPreview->palette().color(ui->fontPreview->backgroundRole()); - m_colors.reset(new LogColorCache(origForeground, origBackground)); - - ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); - ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); - - defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); - - m_languageModel = MMC->translations(); - loadSettings(); - - if(BuildConfig.UPDATER_ENABLED) - { - QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &MultiMCPage::refreshUpdateChannelList); - - if (MMC->updateChecker()->hasChannels()) - { - refreshUpdateChannelList(); - } - else - { - MMC->updateChecker()->updateChanList(false); - } - } - else - { - ui->updateSettingsBox->setHidden(true); - } - // Analytics - if(BuildConfig.ANALYTICS_ID.isEmpty()) - { - ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab)); - } - connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview())); - connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview())); - - //move mac data button - QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); - if (!file.exists()) - { - ui->migrateDataFolderMacBtn->setVisible(false); - } -} - -MultiMCPage::~MultiMCPage() -{ - delete ui; - delete defaultFormat; -} - -bool MultiMCPage::apply() -{ - applySettings(); - return true; -} - -void MultiMCPage::on_instDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text()); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { - QString cooked_dir = FS::NormalizePath(raw_dir); - if (FS::checkProblemticPathJava(QDir(cooked_dir))) - { - QMessageBox warning; - warning.setText(tr("You're trying to specify an instance folder which\'s path " - "contains at least one \'!\'. " - "Java is known to cause problems if that is the case, your " - "instances (probably) won't start!")); - warning.setInformativeText( - tr("Do you really want to use this path? " - "Selecting \"No\" will close this and not alter your instance path.")); - warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - int result = warning.exec(); - if (result == QMessageBox::Yes) - { - ui->instDirTextBox->setText(cooked_dir); - } - } - else - { - ui->instDirTextBox->setText(cooked_dir); - } - } -} - -void MultiMCPage::on_iconsDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text()); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { - QString cooked_dir = FS::NormalizePath(raw_dir); - ui->iconsDirTextBox->setText(cooked_dir); - } -} -void MultiMCPage::on_modsDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text()); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!raw_dir.isEmpty() && QDir(raw_dir).exists()) - { - QString cooked_dir = FS::NormalizePath(raw_dir); - ui->modsDirTextBox->setText(cooked_dir); - } -} -void MultiMCPage::on_migrateDataFolderMacBtn_clicked() -{ - QFile file(QDir::current().absolutePath() + "/dontmovemacdata"); - file.remove(); - QProcess::startDetached(qApp->arguments()[0]); - qApp->quit(); -} - -void MultiMCPage::refreshUpdateChannelList() -{ - // Stop listening for selection changes. It's going to change a lot while we update it and - // we don't need to update the - // description label constantly. - QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(updateChannelSelectionChanged(int))); - - QList channelList = MMC->updateChecker()->getChannelList(); - ui->updateChannelComboBox->clear(); - int selection = -1; - for (int i = 0; i < channelList.count(); i++) - { - UpdateChecker::ChannelListEntry entry = channelList.at(i); - - // When it comes to selection, we'll rely on the indexes of a channel entry being the - // same in the - // combo box as it is in the update checker's channel list. - // This probably isn't very safe, but the channel list doesn't change often enough (or - // at all) for - // this to be a big deal. Hope it doesn't break... - ui->updateChannelComboBox->addItem(entry.name); - - // If the update channel we just added was the selected one, set the current index in - // the combo box to it. - if (entry.id == m_currentUpdateChannel) - { - qDebug() << "Selected index" << i << "channel id" << m_currentUpdateChannel; - selection = i; - } - } - - ui->updateChannelComboBox->setCurrentIndex(selection); - - // Start listening for selection changes again and update the description label. - QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(updateChannelSelectionChanged(int))); - refreshUpdateChannelDesc(); - - // Now that we've updated the channel list, we can enable the combo box. - // It starts off disabled so that if the channel list hasn't been loaded, it will be - // disabled. - ui->updateChannelComboBox->setEnabled(true); -} - -void MultiMCPage::updateChannelSelectionChanged(int index) -{ - refreshUpdateChannelDesc(); -} - -void MultiMCPage::refreshUpdateChannelDesc() -{ - // Get the channel list. - QList channelList = MMC->updateChecker()->getChannelList(); - int selectedIndex = ui->updateChannelComboBox->currentIndex(); - if (selectedIndex < 0) - { - return; - } - if (selectedIndex < channelList.count()) - { - // Find the channel list entry with the given index. - UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex); - - // Set the description text. - ui->updateChannelDescLabel->setText(selected.description); - - // Set the currently selected channel ID. - m_currentUpdateChannel = selected.id; - } -} - -void MultiMCPage::applySettings() -{ - auto s = MMC->settings(); - - if (ui->resetNotificationsBtn->isChecked()) - { - s->set("ShownNotifications", QString()); - } - - // Updates - s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); - s->set("UpdateChannel", m_currentUpdateChannel); - auto original = s->get("IconTheme").toString(); - //FIXME: make generic - switch (ui->themeComboBox->currentIndex()) - { - case 1: - s->set("IconTheme", "pe_dark"); - break; - case 2: - s->set("IconTheme", "pe_light"); - break; - case 3: - s->set("IconTheme", "pe_blue"); - break; - case 4: - s->set("IconTheme", "pe_colored"); - break; - case 5: - s->set("IconTheme", "OSX"); - break; - case 6: - s->set("IconTheme", "iOS"); - break; - case 7: - s->set("IconTheme", "flat"); - break; - case 8: - s->set("IconTheme", "custom"); - break; - case 0: - default: - s->set("IconTheme", "multimc"); - break; - } - - if(original != s->get("IconTheme")) - { - MMC->setIconTheme(s->get("IconTheme").toString()); - } - - auto originalAppTheme = s->get("ApplicationTheme").toString(); - auto newAppTheme = ui->themeComboBoxColors->currentData().toString(); - if(originalAppTheme != newAppTheme) - { - s->set("ApplicationTheme", newAppTheme); - MMC->setApplicationTheme(newAppTheme, false); - } - - // Console settings - s->set("ShowConsole", ui->showConsoleCheck->isChecked()); - s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); - s->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked()); - QString consoleFontFamily = ui->consoleFont->currentFont().family(); - s->set("ConsoleFont", consoleFontFamily); - s->set("ConsoleFontSize", ui->fontSizeBox->value()); - s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value()); - s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked); - - // Folders - // TODO: Offer to move instances to new instance folder. - s->set("InstanceDir", ui->instDirTextBox->text()); - s->set("CentralModsDir", ui->modsDirTextBox->text()); - s->set("IconsDir", ui->iconsDirTextBox->text()); - - auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); - switch (sortMode) - { - case Sort_LastLaunch: - s->set("InstSortMode", "LastLaunch"); - break; - case Sort_Name: - default: - s->set("InstSortMode", "Name"); - break; - } - - // Analytics - if(!BuildConfig.ANALYTICS_ID.isEmpty()) - { - s->set("Analytics", ui->analyticsCheck->isChecked()); - } -} -void MultiMCPage::loadSettings() -{ - auto s = MMC->settings(); - // Updates - ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); - m_currentUpdateChannel = s->get("UpdateChannel").toString(); - //FIXME: make generic - auto theme = s->get("IconTheme").toString(); - if (theme == "pe_dark") - { - ui->themeComboBox->setCurrentIndex(1); - } - else if (theme == "pe_light") - { - ui->themeComboBox->setCurrentIndex(2); - } - else if (theme == "pe_blue") - { - ui->themeComboBox->setCurrentIndex(3); - } - else if (theme == "pe_colored") - { - ui->themeComboBox->setCurrentIndex(4); - } - else if (theme == "OSX") - { - ui->themeComboBox->setCurrentIndex(5); - } - else if (theme == "iOS") - { - ui->themeComboBox->setCurrentIndex(6); - } - else if (theme == "flat") - { - ui->themeComboBox->setCurrentIndex(7); - } - else if (theme == "custom") - { - ui->themeComboBox->setCurrentIndex(8); - } - else - { - ui->themeComboBox->setCurrentIndex(0); - } - - { - auto currentTheme = s->get("ApplicationTheme").toString(); - auto themes = MMC->getValidApplicationThemes(); - int idx = 0; - for(auto &theme: themes) - { - ui->themeComboBoxColors->addItem(theme->name(), theme->id()); - if(currentTheme == theme->id()) - { - ui->themeComboBoxColors->setCurrentIndex(idx); - } - idx++; - } - } - - // Console settings - ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); - ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); - ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool()); - QString fontFamily = MMC->settings()->get("ConsoleFont").toString(); - QFont consoleFont(fontFamily); - ui->consoleFont->setCurrentFont(consoleFont); - - bool conversionOk = true; - int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk); - if(!conversionOk) - { - fontSize = 11; - } - ui->fontSizeBox->setValue(fontSize); - refreshFontPreview(); - ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt()); - ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool()); - - // Folders - ui->instDirTextBox->setText(s->get("InstanceDir").toString()); - ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); - ui->iconsDirTextBox->setText(s->get("IconsDir").toString()); - - QString sortMode = s->get("InstSortMode").toString(); - - if (sortMode == "LastLaunch") - { - ui->sortLastLaunchedBtn->setChecked(true); - } - else - { - ui->sortByNameBtn->setChecked(true); - } - - // Analytics - if(!BuildConfig.ANALYTICS_ID.isEmpty()) - { - ui->analyticsCheck->setChecked(s->get("Analytics").toBool()); - } -} - -void MultiMCPage::refreshFontPreview() -{ - int fontSize = ui->fontSizeBox->value(); - QString fontFamily = ui->consoleFont->currentFont().family(); - ui->fontPreview->clear(); - defaultFormat->setFont(QFont(fontFamily, fontSize)); - { - QTextCharFormat format(*defaultFormat); - format.setForeground(m_colors->getFront(MessageLevel::Error)); - // append a paragraph/line - auto workCursor = ui->fontPreview->textCursor(); - workCursor.movePosition(QTextCursor::End); - workCursor.insertText(tr("[Something/ERROR] A spooky error!"), format); - workCursor.insertBlock(); - } - { - QTextCharFormat format(*defaultFormat); - format.setForeground(m_colors->getFront(MessageLevel::Message)); - // append a paragraph/line - auto workCursor = ui->fontPreview->textCursor(); - workCursor.movePosition(QTextCursor::End); - workCursor.insertText(tr("[Test/INFO] A harmless message..."), format); - workCursor.insertBlock(); - } - { - QTextCharFormat format(*defaultFormat); - format.setForeground(m_colors->getFront(MessageLevel::Warning)); - // append a paragraph/line - auto workCursor = ui->fontPreview->textCursor(); - workCursor.movePosition(QTextCursor::End); - workCursor.insertText(tr("[Something/WARN] A not so spooky warning."), format); - workCursor.insertBlock(); - } -} diff --git a/launcher/pages/global/MultiMCPage.h b/launcher/pages/global/MultiMCPage.h deleted file mode 100644 index fae75bf2..00000000 --- a/launcher/pages/global/MultiMCPage.h +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 -#include - -#include "java/JavaChecker.h" -#include "pages/BasePage.h" -#include -#include "ColorCache.h" -#include - -class QTextCharFormat; -class SettingsObject; - -namespace Ui -{ -class MultiMCPage; -} - -class MultiMCPage : public QWidget, public BasePage -{ - Q_OBJECT - -public: - explicit MultiMCPage(QWidget *parent = 0); - ~MultiMCPage(); - - QString displayName() const override - { - return "MultiMC"; - } - QIcon icon() const override - { - return MMC->getThemedIcon("multimc"); - } - QString id() const override - { - return "multimc-settings"; - } - QString helpPage() const override - { - return "MultiMC-settings"; - } - bool apply() override; - -private: - void applySettings(); - void loadSettings(); - -private -slots: - void on_instDirBrowseBtn_clicked(); - void on_modsDirBrowseBtn_clicked(); - void on_iconsDirBrowseBtn_clicked(); - void on_migrateDataFolderMacBtn_clicked(); - - /*! - * Updates the list of update channels in the combo box. - */ - void refreshUpdateChannelList(); - - /*! - * Updates the channel description label. - */ - void refreshUpdateChannelDesc(); - - /*! - * Updates the font preview - */ - void refreshFontPreview(); - - void updateChannelSelectionChanged(int index); - -private: - Ui::MultiMCPage *ui; - - /*! - * Stores the currently selected update channel. - */ - QString m_currentUpdateChannel; - - // default format for the font preview... - QTextCharFormat *defaultFormat; - - std::unique_ptr m_colors; - - std::shared_ptr m_languageModel; -}; diff --git a/launcher/pages/global/MultiMCPage.ui b/launcher/pages/global/MultiMCPage.ui deleted file mode 100644 index 4ad20242..00000000 --- a/launcher/pages/global/MultiMCPage.ui +++ /dev/null @@ -1,584 +0,0 @@ - - - MultiMCPage - - - - 0 - 0 - 514 - 629 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QTabWidget::Rounded - - - 0 - - - - Features - - - - - - Update Settings - - - - - - Check for updates when MultiMC starts? - - - - - - - Up&date Channel: - - - updateChannelComboBox - - - - - - - false - - - - - - - No channel selected. - - - true - - - - - - - - - - Folders - - - - - - I&nstances: - - - instDirTextBox - - - - - - - - - - ... - - - - - - - &Mods: - - - modsDirTextBox - - - - - - - - - - ... - - - - - - - - - - &Icons: - - - iconsDirTextBox - - - - - - - ... - - - - - - - - - - Move MultiMC data to new location (will restart MultiMC) - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - User Interface - - - - - - MultiMC notifications - - - - - - Reset hidden notifications - - - true - - - - - - - - - - true - - - Instance view sorting mode - - - - - - By &last launched - - - sortingModeGroup - - - - - - - By &name - - - sortingModeGroup - - - - - - - - - - Theme - - - - - - &Icons - - - themeComboBox - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - Default - - - - - Simple (Dark Icons) - - - - - Simple (Light Icons) - - - - - Simple (Blue Icons) - - - - - Simple (Colored Icons) - - - - - OSX - - - - - iOS - - - - - Flat - - - - - Custom - - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - Colors - - - themeComboBoxColors - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - Console - - - - - - Console Settings - - - - - - Show console while the game is running? - - - - - - - Automatically close console when the game quits? - - - - - - - Show console when the game crashes? - - - - - - - - - - History limit - - - - - - Stop logging when log overflows - - - - - - - - 0 - 0 - - - - lines - - - 10000 - - - 1000000 - - - 10000 - - - 100000 - - - - - - - - - - - 0 - 0 - - - - Console font - - - - - - - 0 - 0 - - - - Qt::ScrollBarAlwaysOff - - - false - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - - - - - 5 - - - 16 - - - 11 - - - - - - - - - - - Analytics - - - - - - Analytics Settings - - - - - - Send anonymous usage statistics? - - - - - - - Qt::Horizontal - - - - - - - <html><head/> -<body> -<p>MultiMC sends anonymous usage statistics on every start of the application.</p><p>The following data is collected:</p> -<ul> -<li>MultiMC version.</li> -<li>Operating system name, version and architecture.</li> -<li>CPU architecture (kernel architecture on linux).</li> -<li>Size of system memory.</li> -<li>Java version, architecture and memory settings.</li> -</ul> -</body></html> - - - true - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - tabWidget - autoUpdateCheckBox - updateChannelComboBox - instDirTextBox - instDirBrowseBtn - modsDirTextBox - modsDirBrowseBtn - iconsDirTextBox - iconsDirBrowseBtn - resetNotificationsBtn - sortLastLaunchedBtn - sortByNameBtn - themeComboBox - themeComboBoxColors - showConsoleCheck - autoCloseConsoleCheck - showConsoleErrorCheck - lineLimitSpinBox - checkStopLogging - consoleFont - fontSizeBox - fontPreview - - - - - - - diff --git a/launcher/pages/global/PasteEEPage.cpp b/launcher/pages/global/PasteEEPage.cpp index f932dede..9f7a7efb 100644 --- a/launcher/pages/global/PasteEEPage.cpp +++ b/launcher/pages/global/PasteEEPage.cpp @@ -23,7 +23,7 @@ #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" -#include "MultiMC.h" +#include "Launcher.h" PasteEEPage::PasteEEPage(QWidget *parent) : QWidget(parent), @@ -42,7 +42,7 @@ PasteEEPage::~PasteEEPage() void PasteEEPage::loadSettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); QString keyToUse = s->get("PasteEEAPIKey").toString(); if(keyToUse == "multimc") { @@ -57,7 +57,7 @@ void PasteEEPage::loadSettings() void PasteEEPage::applySettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); QString pasteKeyToUse; if (ui->customButton->isChecked()) diff --git a/launcher/pages/global/PasteEEPage.h b/launcher/pages/global/PasteEEPage.h index 001decdb..c99cd51e 100644 --- a/launcher/pages/global/PasteEEPage.h +++ b/launcher/pages/global/PasteEEPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { class PasteEEPage; @@ -38,7 +38,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("log"); + return LAUNCHER->getThemedIcon("log"); } QString id() const override { diff --git a/launcher/pages/global/ProxyPage.cpp b/launcher/pages/global/ProxyPage.cpp index 809059ff..d4e767e1 100644 --- a/launcher/pages/global/ProxyPage.cpp +++ b/launcher/pages/global/ProxyPage.cpp @@ -19,7 +19,7 @@ #include #include "settings/SettingsObject.h" -#include "MultiMC.h" +#include "Launcher.h" #include "Env.h" ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage) @@ -58,7 +58,7 @@ void ProxyPage::proxyChanged(int) void ProxyPage::applySettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Proxy QString proxyType = "None"; @@ -82,7 +82,7 @@ void ProxyPage::applySettings() } void ProxyPage::loadSettings() { - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Proxy QString proxyType = s->get("ProxyType").toString(); if (proxyType == "Default") diff --git a/launcher/pages/global/ProxyPage.h b/launcher/pages/global/ProxyPage.h index ff94ec49..90c33c9d 100644 --- a/launcher/pages/global/ProxyPage.h +++ b/launcher/pages/global/ProxyPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -40,7 +40,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("proxy"); + return LAUNCHER->getThemedIcon("proxy"); } QString id() const override { diff --git a/launcher/pages/instance/GameOptionsPage.h b/launcher/pages/instance/GameOptionsPage.h index 0fd2fbff..ca7e31b1 100644 --- a/launcher/pages/instance/GameOptionsPage.h +++ b/launcher/pages/instance/GameOptionsPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("settings"); + return LAUNCHER->getThemedIcon("settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/InstanceSettingsPage.cpp b/launcher/pages/instance/InstanceSettingsPage.cpp index 7bd424c0..c83832c6 100644 --- a/launcher/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/pages/instance/InstanceSettingsPage.cpp @@ -7,7 +7,7 @@ #include "dialogs/VersionSelectDialog.h" #include "JavaCommon.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -22,8 +22,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(MMC, &MultiMC::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); - connect(MMC, &MultiMC::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); + connect(LAUNCHER, &Launcher::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings); + connect(LAUNCHER, &Launcher::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings); loadSettings(); } @@ -41,13 +41,13 @@ void InstanceSettingsPage::globalSettingsButtonClicked(bool) { switch(ui->settingsTabs->currentIndex()) { case 0: - MMC->ShowGlobalSettings(this, "java-settings"); + LAUNCHER->ShowGlobalSettings(this, "java-settings"); return; case 1: - MMC->ShowGlobalSettings(this, "minecraft-settings"); + LAUNCHER->ShowGlobalSettings(this, "minecraft-settings"); return; case 2: - MMC->ShowGlobalSettings(this, "custom-commands"); + LAUNCHER->ShowGlobalSettings(this, "custom-commands"); return; } } @@ -278,7 +278,7 @@ void InstanceSettingsPage::on_javaDetectBtn_clicked() { JavaInstallPtr java; - VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true); + VersionSelectDialog vselect(LAUNCHER->javalist().get(), tr("Select a Java version"), this, true); vselect.setResizeOn(2); vselect.exec(); diff --git a/launcher/pages/instance/InstanceSettingsPage.h b/launcher/pages/instance/InstanceSettingsPage.h index 068213a8..a039101c 100644 --- a/launcher/pages/instance/InstanceSettingsPage.h +++ b/launcher/pages/instance/InstanceSettingsPage.h @@ -22,7 +22,7 @@ #include #include "pages/BasePage.h" #include "JavaCommon.h" -#include "MultiMC.h" +#include "Launcher.h" class JavaChecker; namespace Ui @@ -43,7 +43,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("instance-settings"); + return LAUNCHER->getThemedIcon("instance-settings"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LegacyUpgradePage.cpp b/launcher/pages/instance/LegacyUpgradePage.cpp index af800b03..b12174fa 100644 --- a/launcher/pages/instance/LegacyUpgradePage.cpp +++ b/launcher/pages/instance/LegacyUpgradePage.cpp @@ -4,7 +4,7 @@ #include "InstanceList.h" #include "minecraft/legacy/LegacyInstance.h" #include "minecraft/legacy/LegacyUpgradeTask.h" -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/ProgressDialog.h" @@ -38,9 +38,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(MMC->instances()->getInstanceGroup(m_inst->id())); + upgradeTask->setGroup(LAUNCHER->instances()->getInstanceGroup(m_inst->id())); upgradeTask->setIcon(m_inst->iconKey()); - unique_qobject_ptr task(MMC->instances()->wrapInstanceTask(upgradeTask)); + unique_qobject_ptr task(LAUNCHER->instances()->wrapInstanceTask(upgradeTask)); runModalTask(task.get()); } diff --git a/launcher/pages/instance/LegacyUpgradePage.h b/launcher/pages/instance/LegacyUpgradePage.h index df34e33a..d8e98f6b 100644 --- a/launcher/pages/instance/LegacyUpgradePage.h +++ b/launcher/pages/instance/LegacyUpgradePage.h @@ -19,7 +19,7 @@ #include "minecraft/legacy/LegacyInstance.h" #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -40,7 +40,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("checkupdate"); + return LAUNCHER->getThemedIcon("checkupdate"); } virtual QString id() const override { diff --git a/launcher/pages/instance/LogPage.cpp b/launcher/pages/instance/LogPage.cpp index 3d2085c6..2399b55d 100644 --- a/launcher/pages/instance/LogPage.cpp +++ b/launcher/pages/instance/LogPage.cpp @@ -1,7 +1,7 @@ #include "LogPage.h" #include "ui_LogPage.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -124,9 +124,9 @@ LogPage::LogPage(InstancePtr instance, QWidget *parent) // set up fonts in the log proxy { - QString fontFamily = MMC->settings()->get("ConsoleFont").toString(); + QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/LogPage.h b/launcher/pages/instance/LogPage.h index b0b0e04b..285296cd 100644 --- a/launcher/pages/instance/LogPage.h +++ b/launcher/pages/instance/LogPage.h @@ -20,7 +20,7 @@ #include "BaseInstance.h" #include "launch/LaunchTask.h" #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -42,7 +42,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("log"); + return LAUNCHER->getThemedIcon("log"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ModFolderPage.cpp b/launcher/pages/instance/ModFolderPage.cpp index 98f20e77..caa81958 100644 --- a/launcher/pages/instance/ModFolderPage.cpp +++ b/launcher/pages/instance/ModFolderPage.cpp @@ -22,7 +22,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/CustomMessageBox.h" #include #include "minecraft/mod/ModFolderModel.h" @@ -301,7 +301,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), MMC->settings()->get("CentralModsDir").toString(), + m_fileSelectionFilter.arg(m_displayName), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); if (!list.empty()) { diff --git a/launcher/pages/instance/ModFolderPage.h b/launcher/pages/instance/ModFolderPage.h index f653a8c0..38fcc6a5 100644 --- a/launcher/pages/instance/ModFolderPage.h +++ b/launcher/pages/instance/ModFolderPage.h @@ -19,7 +19,7 @@ #include "minecraft/MinecraftInstance.h" #include "pages/BasePage.h" -#include +#include class ModFolderModel; namespace Ui @@ -54,7 +54,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon(m_iconName); + return LAUNCHER->getThemedIcon(m_iconName); } virtual QString id() const override { diff --git a/launcher/pages/instance/NotesPage.h b/launcher/pages/instance/NotesPage.h index d0c00ac1..1bdb352d 100644 --- a/launcher/pages/instance/NotesPage.h +++ b/launcher/pages/instance/NotesPage.h @@ -19,7 +19,7 @@ #include "BaseInstance.h" #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -39,9 +39,9 @@ public: } virtual QIcon icon() const override { - auto icon = MMC->getThemedIcon("notes"); + auto icon = LAUNCHER->getThemedIcon("notes"); if(icon.isNull()) - icon = MMC->getThemedIcon("news"); + icon = LAUNCHER->getThemedIcon("news"); return icon; } virtual QString id() const override diff --git a/launcher/pages/instance/OtherLogsPage.cpp b/launcher/pages/instance/OtherLogsPage.cpp index b67b84bd..31cd44ed 100644 --- a/launcher/pages/instance/OtherLogsPage.cpp +++ b/launcher/pages/instance/OtherLogsPage.cpp @@ -129,9 +129,9 @@ void OtherLogsPage::on_btnReload_clicked() { auto setPlainText = [&](const QString & text) { - QString fontFamily = MMC->settings()->get("ConsoleFont").toString(); + QString fontFamily = LAUNCHER->settings()->get("ConsoleFont").toString(); bool conversionOk = false; - int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk); + int fontSize = LAUNCHER->settings()->get("ConsoleFontSize").toInt(&conversionOk); if(!conversionOk) { fontSize = 11; diff --git a/launcher/pages/instance/OtherLogsPage.h b/launcher/pages/instance/OtherLogsPage.h index 7f21c0fa..25f127f6 100644 --- a/launcher/pages/instance/OtherLogsPage.h +++ b/launcher/pages/instance/OtherLogsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include namespace Ui @@ -46,7 +46,7 @@ public: } QIcon icon() const override { - return MMC->getThemedIcon("log"); + return LAUNCHER->getThemedIcon("log"); } QString helpPage() const override { diff --git a/launcher/pages/instance/ScreenshotsPage.cpp b/launcher/pages/instance/ScreenshotsPage.cpp index efa0f9f2..172e2eb3 100644 --- a/launcher/pages/instance/ScreenshotsPage.cpp +++ b/launcher/pages/instance/ScreenshotsPage.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include "dialogs/ProgressDialog.h" #include "dialogs/CustomMessageBox.h" @@ -104,7 +104,7 @@ public: { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared(); - m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder")); + m_thumbnailCache->add("placeholder", LAUNCHER->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); // FIXME: the watched file set is not updated when files are removed } diff --git a/launcher/pages/instance/ScreenshotsPage.h b/launcher/pages/instance/ScreenshotsPage.h index 03a809de..01f26642 100644 --- a/launcher/pages/instance/ScreenshotsPage.h +++ b/launcher/pages/instance/ScreenshotsPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include class QFileSystemModel; class QIdentityProxyModel; @@ -53,7 +53,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("screenshots"); + return LAUNCHER->getThemedIcon("screenshots"); } virtual QString id() const override { diff --git a/launcher/pages/instance/ServersPage.cpp b/launcher/pages/instance/ServersPage.cpp index d63c6e70..6c55fdac 100644 --- a/launcher/pages/instance/ServersPage.cpp +++ b/launcher/pages/instance/ServersPage.cpp @@ -324,7 +324,7 @@ public: if(px.loadFromData(bytes)) return QIcon(px); } - return MMC->getThemedIcon("unknown_server"); + return LAUNCHER->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; - MMC->launch(m_inst, true, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); + LAUNCHER->launch(m_inst, true, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); } #include "ServersPage.moc" diff --git a/launcher/pages/instance/ServersPage.h b/launcher/pages/instance/ServersPage.h index 8c5b7eb8..63f3b9e3 100644 --- a/launcher/pages/instance/ServersPage.h +++ b/launcher/pages/instance/ServersPage.h @@ -19,7 +19,7 @@ #include #include "pages/BasePage.h" -#include +#include namespace Ui { @@ -47,7 +47,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("unknown_server"); + return LAUNCHER->getThemedIcon("unknown_server"); } virtual QString id() const override { diff --git a/launcher/pages/instance/VersionPage.cpp b/launcher/pages/instance/VersionPage.cpp index 20cb2c9f..103f0c7a 100644 --- a/launcher/pages/instance/VersionPage.cpp +++ b/launcher/pages/instance/VersionPage.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -70,14 +70,14 @@ public: auto string = var.toString(); if(string == "warning") { - return MMC->getThemedIcon("status-yellow"); + return LAUNCHER->getThemedIcon("status-yellow"); } else if(string == "error") { - return MMC->getThemedIcon("status-bad"); + return LAUNCHER->getThemedIcon("status-bad"); } } - return MMC->getThemedIcon("status-good"); + return LAUNCHER->getThemedIcon("status-good"); } return var; } @@ -93,7 +93,7 @@ private: QIcon VersionPage::icon() const { - return MMC->icons()->getIcon(m_inst->iconKey()); + return LAUNCHER->icons()->getIcon(m_inst->iconKey()); } bool VersionPage::shouldDisplay() const { @@ -297,7 +297,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)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!list.empty()) { m_profile->installJarMods(list); @@ -307,7 +307,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)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget()); + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), LAUNCHER->settings()->get("CentralModsDir").toString(), this->parentWidget()); if(!jarPath.isEmpty()) { m_profile->installCustomJar(jarPath); @@ -395,7 +395,7 @@ void VersionPage::on_actionChange_version_triggered() void VersionPage::on_actionDownload_All_triggered() { - if (!MMC->accounts()->anyAccountIsValid()) + if (!LAUNCHER->accounts()->anyAccountIsValid()) { CustomMessageBox::selectable( this, tr("Error"), @@ -614,7 +614,7 @@ void VersionPage::on_actionEdit_triggered() qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; return; } - MMC->openJsonEditor(filename); + LAUNCHER->openJsonEditor(filename); } void VersionPage::on_actionRevert_triggered() diff --git a/launcher/pages/instance/WorldListPage.cpp b/launcher/pages/instance/WorldListPage.cpp index 119cff3e..d25f23a8 100644 --- a/launcher/pages/instance/WorldListPage.cpp +++ b/launcher/pages/instance/WorldListPage.cpp @@ -26,7 +26,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include #include #include @@ -48,7 +48,7 @@ public: auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString(); if(iconFile.isNull()) { // NOTE: Minecraft uses the same placeholder for servers AND worlds - return MMC->getThemedIcon("unknown_server"); + return LAUNCHER->getThemedIcon("unknown_server"); } return QIcon(iconFile); } @@ -218,7 +218,7 @@ void WorldListPage::on_actionCopy_Seed_triggered() return; } int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong(); - MMC->clipboard()->setText(QString::number(seed)); + LAUNCHER->clipboard()->setText(QString::number(seed)); } void WorldListPage::on_actionMCEdit_triggered() @@ -226,7 +226,7 @@ void WorldListPage::on_actionMCEdit_triggered() if(m_mceditStarting) return; - auto mcedit = MMC->mcedit(); + auto mcedit = LAUNCHER->mcedit(); const QString mceditPath = mcedit->path(); diff --git a/launcher/pages/instance/WorldListPage.h b/launcher/pages/instance/WorldListPage.h index 4fc9aa09..b90d7ad1 100644 --- a/launcher/pages/instance/WorldListPage.h +++ b/launcher/pages/instance/WorldListPage.h @@ -19,7 +19,7 @@ #include "minecraft/MinecraftInstance.h" #include "pages/BasePage.h" -#include +#include #include class WorldList; @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("worlds"); + return LAUNCHER->getThemedIcon("worlds"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ImportPage.cpp b/launcher/pages/modplatform/ImportPage.cpp index c2369bdc..dd02e839 100644 --- a/launcher/pages/modplatform/ImportPage.cpp +++ b/launcher/pages/modplatform/ImportPage.cpp @@ -1,7 +1,7 @@ #include "ImportPage.h" #include "ui_ImportPage.h" -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/NewInstanceDialog.h" #include #include diff --git a/launcher/pages/modplatform/ImportPage.h b/launcher/pages/modplatform/ImportPage.h index 67e3c201..cc8a0d1f 100644 --- a/launcher/pages/modplatform/ImportPage.h +++ b/launcher/pages/modplatform/ImportPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("viewfolder"); + return LAUNCHER->getThemedIcon("viewfolder"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/VanillaPage.cpp b/launcher/pages/modplatform/VanillaPage.cpp index 02638315..1cf5bbc7 100644 --- a/launcher/pages/modplatform/VanillaPage.cpp +++ b/launcher/pages/modplatform/VanillaPage.cpp @@ -1,7 +1,7 @@ #include "VanillaPage.h" #include "ui_VanillaPage.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include diff --git a/launcher/pages/modplatform/VanillaPage.h b/launcher/pages/modplatform/VanillaPage.h index af6fd392..e090d8bb 100644 --- a/launcher/pages/modplatform/VanillaPage.h +++ b/launcher/pages/modplatform/VanillaPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" namespace Ui @@ -41,7 +41,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("minecraft"); + return LAUNCHER->getThemedIcon("minecraft"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/pages/modplatform/atlauncher/AtlListModel.cpp index f3be6198..99d12601 100644 --- a/launcher/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/pages/modplatform/atlauncher/AtlListModel.cpp @@ -1,7 +1,7 @@ #include "AtlListModel.h" #include -#include +#include #include #include @@ -48,7 +48,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.safeName)); } - auto icon = MMC->getThemedIcon("atlauncher-placeholder"); + auto icon = LAUNCHER->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); diff --git a/launcher/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/pages/modplatform/atlauncher/AtlPage.cpp index 9fdf111f..e59e5fe1 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/pages/modplatform/atlauncher/AtlPage.cpp @@ -139,7 +139,7 @@ QVector AtlPage::chooseOptionalMods(QVector mod } QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { - VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false); + VersionSelectDialog vselect(vlist.get(), "Choose Version", LAUNCHER->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/pages/modplatform/atlauncher/AtlPage.h index 932ec6a6..ed872053 100644 --- a/launcher/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/pages/modplatform/atlauncher/AtlPage.h @@ -21,7 +21,7 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "pages/BasePage.h" #include "tasks/Task.h" @@ -45,7 +45,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("atlauncher"); + return LAUNCHER->getThemedIcon("atlauncher"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/flame/FlameModel.cpp b/launcher/pages/modplatform/flame/FlameModel.cpp index 228a88c5..6dd29d21 100644 --- a/launcher/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/pages/modplatform/flame/FlameModel.cpp @@ -1,5 +1,5 @@ #include "FlameModel.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -62,7 +62,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = MMC->getThemedIcon("screenshot-placeholder"); + QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } diff --git a/launcher/pages/modplatform/flame/FlamePage.cpp b/launcher/pages/modplatform/flame/FlamePage.cpp index ade58431..8f798df6 100644 --- a/launcher/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/pages/modplatform/flame/FlamePage.cpp @@ -1,7 +1,7 @@ #include "FlamePage.h" #include "ui_FlamePage.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include "dialogs/NewInstanceDialog.h" #include diff --git a/launcher/pages/modplatform/flame/FlamePage.h b/launcher/pages/modplatform/flame/FlamePage.h index 467bb44b..c3d2630a 100644 --- a/launcher/pages/modplatform/flame/FlamePage.h +++ b/launcher/pages/modplatform/flame/FlamePage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" #include @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("flame"); + return LAUNCHER->getThemedIcon("flame"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/ftb/FtbListModel.cpp b/launcher/pages/modplatform/ftb/FtbListModel.cpp index 98973f2e..7da4c066 100644 --- a/launcher/pages/modplatform/ftb/FtbListModel.cpp +++ b/launcher/pages/modplatform/ftb/FtbListModel.cpp @@ -2,7 +2,7 @@ #include "BuildConfig.h" #include "Env.h" -#include "MultiMC.h" +#include "Launcher.h" #include "Json.h" #include @@ -46,7 +46,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const } else if(role == Qt::DecorationRole) { - QIcon placeholder = MMC->getThemedIcon("screenshot-placeholder"); + QIcon placeholder = LAUNCHER->getThemedIcon("screenshot-placeholder"); auto iter = m_logoMap.find(pack.name); if (iter != m_logoMap.end()) { diff --git a/launcher/pages/modplatform/ftb/FtbPage.h b/launcher/pages/modplatform/ftb/FtbPage.h index c9c93897..da121913 100644 --- a/launcher/pages/modplatform/ftb/FtbPage.h +++ b/launcher/pages/modplatform/ftb/FtbPage.h @@ -20,7 +20,7 @@ #include -#include "MultiMC.h" +#include "Launcher.h" #include "pages/BasePage.h" #include "tasks/Task.h" @@ -44,7 +44,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("ftb_logo"); + return LAUNCHER->getThemedIcon("ftb_logo"); } virtual QString id() const override { diff --git a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/pages/modplatform/legacy_ftb/ListModel.cpp index 32596fb3..78063c5f 100644 --- a/launcher/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/pages/modplatform/legacy_ftb/ListModel.cpp @@ -1,5 +1,5 @@ #include "ListModel.h" -#include "MultiMC.h" +#include "Launcher.h" #include #include @@ -130,7 +130,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { return (m_logoMap.value(pack.logo)); } - QIcon icon = MMC->getThemedIcon("screenshot-placeholder"); + QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logo); return icon; } diff --git a/launcher/pages/modplatform/legacy_ftb/Page.cpp b/launcher/pages/modplatform/legacy_ftb/Page.cpp index a438f76c..6b6a7dcd 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.cpp +++ b/launcher/pages/modplatform/legacy_ftb/Page.cpp @@ -3,7 +3,7 @@ #include -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/NewInstanceDialog.h" #include "modplatform/legacy_ftb/PackFetchTask.h" diff --git a/launcher/pages/modplatform/legacy_ftb/Page.h b/launcher/pages/modplatform/legacy_ftb/Page.h index e840216e..6159cd9d 100644 --- a/launcher/pages/modplatform/legacy_ftb/Page.h +++ b/launcher/pages/modplatform/legacy_ftb/Page.h @@ -20,7 +20,7 @@ #include #include "pages/BasePage.h" -#include +#include #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 MMC->getThemedIcon("ftb_logo"); + return LAUNCHER->getThemedIcon("ftb_logo"); } QString id() const override { diff --git a/launcher/pages/modplatform/technic/TechnicModel.cpp b/launcher/pages/modplatform/technic/TechnicModel.cpp index def30783..cac6fef1 100644 --- a/launcher/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/pages/modplatform/technic/TechnicModel.cpp @@ -15,7 +15,7 @@ #include "TechnicModel.h" #include "Env.h" -#include "MultiMC.h" +#include "Launcher.h" #include "Json.h" #include @@ -47,7 +47,7 @@ QVariant Technic::ListModel::data(const QModelIndex& index, int role) const { return (m_logoMap.value(pack.logoName)); } - QIcon icon = MMC->getThemedIcon("screenshot-placeholder"); + QIcon icon = LAUNCHER->getThemedIcon("screenshot-placeholder"); ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); return icon; } diff --git a/launcher/pages/modplatform/technic/TechnicPage.cpp b/launcher/pages/modplatform/technic/TechnicPage.cpp index e836f767..4f27e685 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.cpp +++ b/launcher/pages/modplatform/technic/TechnicPage.cpp @@ -16,7 +16,7 @@ #include "TechnicPage.h" #include "ui_TechnicPage.h" -#include "MultiMC.h" +#include "Launcher.h" #include "dialogs/NewInstanceDialog.h" #include "TechnicModel.h" #include diff --git a/launcher/pages/modplatform/technic/TechnicPage.h b/launcher/pages/modplatform/technic/TechnicPage.h index 27e1258a..f0619a52 100644 --- a/launcher/pages/modplatform/technic/TechnicPage.h +++ b/launcher/pages/modplatform/technic/TechnicPage.h @@ -18,7 +18,7 @@ #include #include "pages/BasePage.h" -#include +#include #include "tasks/Task.h" #include "TechnicData.h" @@ -46,7 +46,7 @@ public: } virtual QIcon icon() const override { - return MMC->getThemedIcon("technic"); + return LAUNCHER->getThemedIcon("technic"); } virtual QString id() const override { diff --git a/launcher/resources/MultiMC.icns b/launcher/resources/MultiMC.icns deleted file mode 100644 index c4eb59d5..00000000 Binary files a/launcher/resources/MultiMC.icns and /dev/null differ diff --git a/launcher/resources/MultiMC.ico b/launcher/resources/MultiMC.ico deleted file mode 100644 index a86a1f0d..00000000 Binary files a/launcher/resources/MultiMC.ico and /dev/null differ diff --git a/launcher/resources/MultiMC.manifest b/launcher/resources/MultiMC.manifest deleted file mode 100644 index 9278f6e4..00000000 --- a/launcher/resources/MultiMC.manifest +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - Custom Minecraft launcher for managing multiple installs. - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/launcher/resources/multimc.rc b/launcher/resources/multimc.rc deleted file mode 100644 index e7340f2a..00000000 --- a/launcher/resources/multimc.rc +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include - -IDI_ICON1 ICON DISCARDABLE "MultiMC.ico" -1 RT_MANIFEST "MultiMC.manifest" - -VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,0,0,0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "CompanyName", "MultiMC Contributors" - VALUE "FileDescription", "MultiMC Launcher" - VALUE "FileVersion", "1.0.0.0" - VALUE "ProductName", "MultiMC" - VALUE "ProductVersion", "5" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0000, 0x04b0 // Unicode - END -END diff --git a/launcher/setupwizard/AnalyticsWizardPage.cpp b/launcher/setupwizard/AnalyticsWizardPage.cpp index 4fb0bcca..3ecc034c 100644 --- a/launcher/setupwizard/AnalyticsWizardPage.cpp +++ b/launcher/setupwizard/AnalyticsWizardPage.cpp @@ -1,5 +1,5 @@ #include "AnalyticsWizardPage.h" -#include +#include #include #include @@ -33,8 +33,8 @@ AnalyticsWizardPage::~AnalyticsWizardPage() bool AnalyticsWizardPage::validatePage() { - auto settings = MMC->settings(); - auto analytics = MMC->analytics(); + auto settings = LAUNCHER->settings(); + auto analytics = LAUNCHER->analytics(); auto status = checkBox->isChecked(); settings->set("AnalyticsSeen", analytics->version()); settings->set("Analytics", status); diff --git a/launcher/setupwizard/JavaWizardPage.cpp b/launcher/setupwizard/JavaWizardPage.cpp index ad571c09..a60090ce 100644 --- a/launcher/setupwizard/JavaWizardPage.cpp +++ b/launcher/setupwizard/JavaWizardPage.cpp @@ -1,5 +1,5 @@ #include "JavaWizardPage.h" -#include +#include #include #include @@ -55,7 +55,7 @@ bool JavaWizardPage::wantsRefreshButton() bool JavaWizardPage::validatePage() { - auto settings = MMC->settings(); + auto settings = LAUNCHER->settings(); auto result = m_java_widget->validate(); switch(result) { @@ -71,7 +71,7 @@ bool JavaWizardPage::validatePage() case JavaSettingsWidget::ValidationStatus::JavaBad: { // Memory - auto s = MMC->settings(); + auto s = LAUNCHER->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/LanguageWizardPage.cpp b/launcher/setupwizard/LanguageWizardPage.cpp index ca93c6f5..6a5fd737 100644 --- a/launcher/setupwizard/LanguageWizardPage.cpp +++ b/launcher/setupwizard/LanguageWizardPage.cpp @@ -1,5 +1,5 @@ #include "LanguageWizardPage.h" -#include +#include #include #include "widgets/LanguageSelectionWidget.h" @@ -28,13 +28,13 @@ bool LanguageWizardPage::wantsRefreshButton() void LanguageWizardPage::refresh() { - auto translations = MMC->translations(); + auto translations = LAUNCHER->translations(); translations->downloadIndex(); } bool LanguageWizardPage::validatePage() { - auto settings = MMC->settings(); + auto settings = LAUNCHER->settings(); QString key = mainWidget->getSelectedLanguageKey(); settings->set("Language", key); return true; diff --git a/launcher/setupwizard/SetupWizard.cpp b/launcher/setupwizard/SetupWizard.cpp index 60a78b8d..31334924 100644 --- a/launcher/setupwizard/SetupWizard.cpp +++ b/launcher/setupwizard/SetupWizard.cpp @@ -5,7 +5,7 @@ #include "AnalyticsWizardPage.h" #include "translations/TranslationsModel.h" -#include +#include #include #include diff --git a/launcher/themes/ITheme.cpp b/launcher/themes/ITheme.cpp index bfec87e7..321b0d9b 100644 --- a/launcher/themes/ITheme.cpp +++ b/launcher/themes/ITheme.cpp @@ -2,7 +2,7 @@ #include "rainbow.h" #include #include -#include "MultiMC.h" +#include "Launcher.h" void ITheme::apply(bool) { @@ -13,11 +13,11 @@ void ITheme::apply(bool) } if(hasStyleSheet()) { - MMC->setStyleSheet(appStyleSheet()); + LAUNCHER->setStyleSheet(appStyleSheet()); } else { - MMC->setStyleSheet(QString()); + LAUNCHER->setStyleSheet(QString()); } QDir::setSearchPaths("theme", searchPaths()); } diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 29a952b0..0093e9b8 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -182,7 +182,7 @@ void readIndex(const QString & path, QMap& languages) auto toplevel_doc = Json::requireDocument(data); auto doc = Json::requireObject(toplevel_doc); auto file_type = Json::requireString(doc, "file_type"); - if(file_type != "MMC-TRANSLATION-INDEX") + if(file_type != "LAUNCHER-TRANSLATION-INDEX") { qCritical() << "Translations Download Failed: index file is of unknown file type" << file_type; return; diff --git a/launcher/widgets/JavaSettingsWidget.cpp b/launcher/widgets/JavaSettingsWidget.cpp index 7f53dc23..672d6115 100644 --- a/launcher/widgets/JavaSettingsWidget.cpp +++ b/launcher/widgets/JavaSettingsWidget.cpp @@ -1,5 +1,5 @@ #include "JavaSettingsWidget.h" -#include +#include #include #include @@ -21,9 +21,9 @@ JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent) { m_availableMemory = Sys::getSystemRam() / Sys::mebibyte; - goodIcon = MMC->getThemedIcon("status-good"); - yellowIcon = MMC->getThemedIcon("status-yellow"); - badIcon = MMC->getThemedIcon("status-bad"); + goodIcon = LAUNCHER->getThemedIcon("status-good"); + yellowIcon = LAUNCHER->getThemedIcon("status-yellow"); + badIcon = LAUNCHER->getThemedIcon("status-bad"); setupUi(); connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int))); @@ -115,9 +115,9 @@ void JavaSettingsWidget::setupUi() void JavaSettingsWidget::initialize() { - m_versionWidget->initialize(MMC->javalist().get()); + m_versionWidget->initialize(LAUNCHER->javalist().get()); m_versionWidget->setResizeOn(2); - auto s = MMC->settings(); + auto s = LAUNCHER->settings(); // Memory observedMinMemory = s->get("MinMemAlloc").toInt(); observedMaxMemory = s->get("MaxMemAlloc").toInt(); diff --git a/launcher/widgets/LanguageSelectionWidget.cpp b/launcher/widgets/LanguageSelectionWidget.cpp index 8d23bdc5..3a8fbd2f 100644 --- a/launcher/widgets/LanguageSelectionWidget.cpp +++ b/launcher/widgets/LanguageSelectionWidget.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "MultiMC.h" +#include "Launcher.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 = MMC->translations(); + auto translations = LAUNCHER->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 = MMC->translations(); + auto translations = LAUNCHER->translations(); return translations->data(languageView->currentIndex(), Qt::UserRole).toString(); } @@ -59,7 +59,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con { return; } - auto translations = MMC->translations(); + auto translations = LAUNCHER->translations(); QString key = translations->data(current, Qt::UserRole).toString(); translations->selectLanguage(key); translations->updateLanguage(key); diff --git a/launcher/widgets/PageContainer.cpp b/launcher/widgets/PageContainer.cpp index 05a5e6b4..978d3e82 100644 --- a/launcher/widgets/PageContainer.cpp +++ b/launcher/widgets/PageContainer.cpp @@ -26,11 +26,11 @@ #include #include -#include "MultiMC.h" +#include "Launcher.h" #include "settings/SettingsObject.h" #include "widgets/IconLabel.h" #include "PageContainer_p.h" -#include +#include #include class PageEntryFilterModel : public QSortFilterProxyModel @@ -139,12 +139,12 @@ void PageContainer::createUI() m_header->setFont(headerLabelFont); QHBoxLayout *headerHLayout = new QHBoxLayout; - const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + const int leftMargin = LAUNCHER->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 = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin); + const int rightMargin = LAUNCHER->style()->pixelMetric(QStyle::PM_LayoutRightMargin); headerHLayout->addSpacerItem(new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); headerHLayout->setContentsMargins(0, 6, 0, 0); @@ -195,7 +195,7 @@ void PageContainer::showPage(int row) { m_pageStack->setCurrentIndex(0); m_header->setText(QString()); - m_iconHeader->setIcon(MMC->getThemedIcon("bug")); + m_iconHeader->setIcon(LAUNCHER->getThemedIcon("bug")); } } diff --git a/libraries/classparser/CMakeLists.txt b/libraries/classparser/CMakeLists.txt index 3fe7591d..c07e871c 100644 --- a/libraries/classparser/CMakeLists.txt +++ b/libraries/classparser/CMakeLists.txt @@ -36,6 +36,6 @@ src/annotations.cpp add_definitions(-DCLASSPARSER_LIBRARY) -add_library(MultiMC_classparser STATIC ${CLASSPARSER_SOURCES} ${CLASSPARSER_HEADERS}) -target_include_directories(MultiMC_classparser PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(MultiMC_classparser MultiMC_quazip Qt5::Core) +add_library(Launcher_classparser STATIC ${CLASSPARSER_SOURCES} ${CLASSPARSER_HEADERS}) +target_include_directories(Launcher_classparser PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(Launcher_classparser Launcher_quazip Qt5::Core) diff --git a/libraries/iconfix/CMakeLists.txt b/libraries/iconfix/CMakeLists.txt index ccf0edea..52a31c68 100644 --- a/libraries/iconfix/CMakeLists.txt +++ b/libraries/iconfix/CMakeLists.txt @@ -12,17 +12,17 @@ internal/qiconloader.cpp internal/qiconloader_p.h ) -add_library(MultiMC_iconfix SHARED ${ICONFIX_SOURCES}) -target_include_directories(MultiMC_iconfix PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_BINARY_DIR}" ) +add_library(Launcher_iconfix SHARED ${ICONFIX_SOURCES}) +target_include_directories(Launcher_iconfix PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_BINARY_DIR}" ) -target_link_libraries(MultiMC_iconfix Qt5::Core Qt5::Widgets) +target_link_libraries(Launcher_iconfix Qt5::Core Qt5::Widgets) -set_target_properties(MultiMC_iconfix PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1) -generate_export_header(MultiMC_iconfix) +set_target_properties(Launcher_iconfix PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1) +generate_export_header(Launcher_iconfix) # Install it install( - TARGETS MultiMC_iconfix + TARGETS Launcher_iconfix RUNTIME DESTINATION ${LIBRARY_DEST_DIR} LIBRARY DESTINATION ${LIBRARY_DEST_DIR} ) \ No newline at end of file diff --git a/libraries/quazip b/libraries/quazip index 3691d57d..b1a72ac0 160000 --- a/libraries/quazip +++ b/libraries/quazip @@ -1 +1 @@ -Subproject commit 3691d57d3af13f49b2be2b62accddefee3c26b9c +Subproject commit b1a72ac0bb5a732bf887a535ab75c6f9bedb6b6b diff --git a/libraries/rainbow/CMakeLists.txt b/libraries/rainbow/CMakeLists.txt index ad806faa..833538e3 100644 --- a/libraries/rainbow/CMakeLists.txt +++ b/libraries/rainbow/CMakeLists.txt @@ -9,14 +9,14 @@ src/rainbow.cpp ) add_definitions(-DRAINBOW_LIBRARY) -add_library(MultiMC_rainbow SHARED ${RAINBOW_SOURCES}) -target_include_directories(MultiMC_rainbow PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +add_library(Launcher_rainbow SHARED ${RAINBOW_SOURCES}) +target_include_directories(Launcher_rainbow PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(MultiMC_rainbow Qt5::Core Qt5::Gui) +target_link_libraries(Launcher_rainbow Qt5::Core Qt5::Gui) # Install it install( - TARGETS MultiMC_rainbow + TARGETS Launcher_rainbow RUNTIME DESTINATION ${LIBRARY_DEST_DIR} LIBRARY DESTINATION ${LIBRARY_DEST_DIR} ) diff --git a/notsecrets/CMakeLists.txt b/notsecrets/CMakeLists.txt index f27aeb70..88504a4d 100644 --- a/notsecrets/CMakeLists.txt +++ b/notsecrets/CMakeLists.txt @@ -2,3 +2,8 @@ add_library(secrets STATIC Secrets.cpp Secrets.h) target_link_libraries(secrets Qt5::Core) target_compile_definitions(secrets PUBLIC -DEMBED_SECRETS) target_include_directories(secrets PUBLIC .) + +set(Launcher_Name "Launcher" PARENT_SCOPE) +set(Launcher_Copyright "MultiMC Contributors" PARENT_SCOPE) + +set(Launcher_Branding_ICNS "notsecrets/Launcher.icns") diff --git a/notsecrets/Launcher.icns b/notsecrets/Launcher.icns new file mode 100644 index 00000000..951b74fc Binary files /dev/null and b/notsecrets/Launcher.icns differ diff --git a/notsecrets/Launcher.ico b/notsecrets/Launcher.ico new file mode 100644 index 00000000..9308958f Binary files /dev/null and b/notsecrets/Launcher.ico differ diff --git a/notsecrets/Launcher.manifest b/notsecrets/Launcher.manifest new file mode 100644 index 00000000..0ee781ee --- /dev/null +++ b/notsecrets/Launcher.manifest @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + Custom Minecraft launcher for managing multiple installs. + + + + + + + + + + + + + + + diff --git a/notsecrets/genicons.sh b/notsecrets/genicons.sh new file mode 100755 index 00000000..e6f704f9 --- /dev/null +++ b/notsecrets/genicons.sh @@ -0,0 +1,18 @@ +#/bin/bash + +inkscape -w 16 -h 16 -o logo_16.png logo.svg +inkscape -w 24 -h 24 -o logo_24.png logo.svg +inkscape -w 32 -h 32 -o logo_32.png logo.svg +inkscape -w 48 -h 48 -o logo_48.png logo.svg +inkscape -w 64 -h 64 -o logo_64.png logo.svg +inkscape -w 128 -h 128 -o logo_128.png logo.svg + +convert logo_128.png logo_64.png logo_48.png logo_32.png logo_24.png logo_16.png Launcher.ico + +inkscape -w 256 -h 256 -o logo_256.png logo.svg +inkscape -w 512 -h 512 -o logo_512.png logo.svg +inkscape -w 1024 -h 1024 -o logo_1024.png logo.svg + +png2icns Launcher.icns logo_1024.png logo_512.png logo_256.png logo_128.png logo_32.png logo_16.png + +rm -f logo_*.png diff --git a/notsecrets/launcher.rc b/notsecrets/launcher.rc new file mode 100644 index 00000000..d7e80888 --- /dev/null +++ b/notsecrets/launcher.rc @@ -0,0 +1,29 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +IDI_ICON1 ICON DISCARDABLE "Laucher.ico" +1 RT_MANIFEST "Laucher.manifest" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,0,0,0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "MultiMC Contributors" + VALUE "FileDescription", "A Minecraft Launcher" + VALUE "FileVersion", "1.0.0.0" + VALUE "ProductName", "Laucher" + VALUE "ProductVersion", "5" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04b0 // Unicode + END +END diff --git a/notsecrets/logo.svg b/notsecrets/logo.svg new file mode 100644 index 00000000..6d32064a --- /dev/null +++ b/notsecrets/logo.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/secrets/multimc.rc b/secrets/multimc.rc new file mode 100644 index 00000000..e7340f2a --- /dev/null +++ b/secrets/multimc.rc @@ -0,0 +1,29 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +IDI_ICON1 ICON DISCARDABLE "MultiMC.ico" +1 RT_MANIFEST "MultiMC.manifest" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,0,0,0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "MultiMC Contributors" + VALUE "FileDescription", "MultiMC Launcher" + VALUE "FileVersion", "1.0.0.0" + VALUE "ProductName", "MultiMC" + VALUE "ProductVersion", "5" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04b0 // Unicode + END +END -- cgit