diff options
-rw-r--r-- | .github/workflows/build.yml | 8 | ||||
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | buildconfig/BuildConfig.cpp.in | 27 | ||||
-rw-r--r-- | buildconfig/BuildConfig.h | 6 | ||||
-rw-r--r-- | cmake/GetGitRevisionDescription.cmake | 246 | ||||
-rw-r--r-- | cmake/GetGitRevisionDescription.cmake.in | 34 | ||||
-rw-r--r-- | launcher/Application.cpp | 31 | ||||
-rw-r--r-- | launcher/Application.h | 12 | ||||
-rw-r--r-- | launcher/net/Download.cpp | 5 | ||||
-rw-r--r-- | launcher/net/Download.h | 1 | ||||
-rw-r--r-- | launcher/net/Upload.cpp | 43 | ||||
-rw-r--r-- | launcher/net/Upload.h | 36 | ||||
-rw-r--r-- | launcher/ui/dialogs/ModDownloadDialog.cpp | 33 | ||||
-rw-r--r-- | launcher/ui/dialogs/ModDownloadDialog.h | 21 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewInstanceDialog.cpp | 27 | ||||
-rw-r--r-- | launcher/ui/dialogs/NewInstanceDialog.h | 41 | ||||
-rw-r--r-- | launcher/ui/pages/global/APIPage.cpp | 16 | ||||
-rw-r--r-- | launcher/ui/pages/global/APIPage.ui | 6 | ||||
-rw-r--r-- | launcher/ui/pages/global/AccountListPage.cpp | 2 | ||||
-rw-r--r-- | launcher/ui/pages/modplatform/ImportPage.ui | 2 | ||||
-rw-r--r-- | program_info/CMakeLists.txt | 23 | ||||
-rw-r--r-- | program_info/polymc.6.scd | 61 | ||||
-rw-r--r-- | program_info/polymc.6.txt | 64 |
23 files changed, 556 insertions, 198 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbbc1417..bc92f37f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -113,9 +113,9 @@ jobs: uses: actions/cache@v3.0.2 with: path: '${{ github.workspace }}\.ccache' - key: ${{ matrix.os }}-${{ matrix.msystem }} + key: ${{ matrix.os }}--qt${{ matrix.qt_ver }} restore-keys: | - ${{ matrix.os }}-${{ matrix.msystem }} + ${{ matrix.os }}--qt${{ matrix.qt_ver }} - name: Set short version shell: bash @@ -127,7 +127,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get -y update - sudo apt-get -y install ninja-build extra-cmake-modules + sudo apt-get -y install ninja-build extra-cmake-modules scdoc - name: Install Dependencies (macOS) if: runner.os == 'macOS' @@ -138,7 +138,7 @@ jobs: - name: Install Qt (Linux) if: runner.os == 'Linux' && matrix.appimage != true run: | - sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5 qt5-image-formats-plugins + sudo apt-get -y install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5 - name: Install Qt (macOS and AppImage) if: matrix.qt_ver == 6 && runner.os != 'Windows' diff --git a/CMakeLists.txt b/CMakeLists.txt index fc9cdd31..c88a32ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,14 +131,16 @@ set(Launcher_MSA_CLIENT_ID "549033b2-1532-4d4e-ae77-1bbaa46f9d74" CACHE STRING " # By using this key in your builds you accept the terms and conditions laid down in # https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions # NOTE: CurseForge requires you to change this if you make any kind of derivative work. -set(Launcher_CURSEFORGE_API_KEY "$2a$10$1Oqr2MX3O4n/ilhFGc597u8tfI3L2Hyr9/rtWDAMRjghSQV2QUuxq" CACHE STRING "CurseForge API Key") +set(Launcher_CURSEFORGE_API_KEY "$2a$10$1Oqr2MX3O4n/ilhFGc597u8tfI3L2Hyr9/rtWDAMRjghSQV2QUuxq" CACHE STRING "API key for the CurseForge platform") #### Check the current Git commit and branch include(GetGitRevisionDescription) +git_get_exact_tag(Launcher_GIT_TAG) get_git_head_revision(Launcher_GIT_REFSPEC Launcher_GIT_COMMIT) message(STATUS "Git commit: ${Launcher_GIT_COMMIT}") +message(STATUS "Git tag: ${Launcher_GIT_TAG}") message(STATUS "Git refspec: ${Launcher_GIT_REFSPEC}") set(Launcher_RELEASE_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}") @@ -263,7 +265,10 @@ elseif(UNIX) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR} RENAME "${Launcher_APP_BINARY_NAME}.6") + + if(Launcher_ManPage) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR}) + endif() # Install basic runner script if component "portable" is selected configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 2d07bc58..7da66f36 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -70,12 +70,18 @@ Config::Config() } GIT_COMMIT = "@Launcher_GIT_COMMIT@"; + GIT_TAG = "@Launcher_GIT_TAG@"; GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; - if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND")) + + // Assume that builds outside of Git repos are "stable" + if (GIT_REFSPEC == QStringLiteral("GITDIR-NOTFOUND") + || GIT_TAG == QStringLiteral("GITDIR-NOTFOUND")) { - VERSION_CHANNEL = QStringLiteral("stable"); + GIT_REFSPEC = "refs/heads/stable"; + GIT_TAG = versionString(); } - else if(GIT_REFSPEC.startsWith("refs/heads/")) + + if (GIT_REFSPEC.startsWith("refs/heads/")) { VERSION_CHANNEL = GIT_REFSPEC; VERSION_CHANNEL.remove("refs/heads/"); @@ -89,7 +95,7 @@ Config::Config() } else { - VERSION_CHANNEL = QObject::tr("unknown"); + VERSION_CHANNEL = "unknown"; } VERSION_STR = "@Launcher_VERSION_STRING@"; @@ -98,7 +104,7 @@ Config::Config() HELP_URL = "@Launcher_HELP_URL@"; IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@"; - CURSEFORGE_API_KEY = "@Launcher_CURSEFORGE_API_KEY@"; + FLAME_API_KEY = "@Launcher_CURSEFORGE_API_KEY@"; META_URL = "@Launcher_META_URL@"; BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; @@ -108,12 +114,17 @@ Config::Config() SUBREDDIT_URL = "@Launcher_SUBREDDIT_URL@"; } +QString Config::versionString() const +{ + return QString("%1.%2.%3").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_HOTFIX); +} + QString Config::printableVersionString() const { - QString vstr = QString("%1.%2.%3").arg(QString::number(VERSION_MAJOR), QString::number(VERSION_MINOR), QString::number(VERSION_HOTFIX)); + QString vstr = versionString(); // If the build is not a main release, append the channel - if(VERSION_CHANNEL != "stable") + if(VERSION_CHANNEL != "stable" && GIT_TAG != vstr) { vstr += "-" + VERSION_CHANNEL; } @@ -121,7 +132,7 @@ QString Config::printableVersionString() const // if a build number is set, also add it to the end if(VERSION_BUILD >= 0) { - vstr += "-" + QString::number(VERSION_BUILD); + vstr += "+build." + QString::number(VERSION_BUILD); } return vstr; } diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index e41d4ba0..95786d82 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -89,6 +89,9 @@ class Config { /// The git commit hash of this build QString GIT_COMMIT; + /// The git tag of this build + QString GIT_TAG; + /// The git refspec of this build QString GIT_REFSPEC; @@ -124,7 +127,7 @@ class Config { /** * Client API key for CurseForge */ - QString CURSEFORGE_API_KEY; + QString FLAME_API_KEY; /** * Metadata repository URL prefix @@ -160,6 +163,7 @@ class Config { QString MODRINTH_STAGING_URL = "https://staging-api.modrinth.com/v2"; QString MODRINTH_PROD_URL = "https://api.modrinth.com/v2"; + QString versionString() const; /** * \brief Converts the Version to a string. * \return The version number in string format (major.minor.revision.build). diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake index 39c2707b..4fbd90db 100644 --- a/cmake/GetGitRevisionDescription.cmake +++ b/cmake/GetGitRevisionDescription.cmake @@ -3,7 +3,7 @@ # These functions force a re-configure on each git commit so that you can # trust the values of the variables in your build system. # -# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...]) +# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR]) # # Returns the refspec and sha hash of the current head revision # @@ -12,20 +12,33 @@ # Returns the results of git describe on the source tree, and adjusting # the output so that it tests false if an error occurs. # +# git_describe_working_tree(<var> [<additional arguments to git describe> ...]) +# +# Returns the results of git describe on the working tree (--dirty option), +# and adjusting the output so that it tests false if an error occurs. +# # git_get_exact_tag(<var> [<additional arguments to git describe> ...]) # # Returns the results of git describe --exact-match on the source tree, # and adjusting the output so that it tests false if there was no exact # matching tag. # +# git_local_changes(<var>) +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# # Requires CMake 2.6 or newer (uses the 'function' command) # # Original Author: -# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> +# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net> # http://academic.cleardefinition.com -# Iowa State University HCI Graduate Program/VRAC # -# Copyright Iowa State University 2009-2010. +# Copyright 2009-2013, Iowa State University. +# Copyright 2013-2020, Ryan Pavlik +# Copyright 2013-2020, Contributors +# SPDX-License-Identifier: BSL-1.0 # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) @@ -39,45 +52,124 @@ set(__get_git_revision_description YES) # to find the path to this module rather than the path to a calling list file get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) -function(get_git_head_revision _refspecvar _hashvar) - set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - set(GIT_DIR "${GIT_PARENT_DIR}/.git") - while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories - set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") - get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) - if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) +# Function _git_find_closest_git_dir finds the next closest .git directory +# that is part of any directory in the path defined by _start_dir. +# The result is returned in the parent scope variable whose name is passed +# as variable _git_dir_var. If no .git directory can be found, the +# function returns an empty string via _git_dir_var. +# +# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and +# neither foo nor bar contain a file/directory .git. This wil return +# C:/bla/.git +# +function(_git_find_closest_git_dir _start_dir _git_dir_var) + set(cur_dir "${_start_dir}") + set(git_dir "${_start_dir}/.git") + while(NOT EXISTS "${git_dir}") + # .git dir not found, search parent directories + set(git_previous_parent "${cur_dir}") + get_filename_component(cur_dir "${cur_dir}" DIRECTORY) + if(cur_dir STREQUAL git_previous_parent) # We have reached the root directory, we are not in git - set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_git_dir_var} + "" + PARENT_SCOPE) return() endif() - set(GIT_DIR "${GIT_PARENT_DIR}/.git") + set(git_dir "${cur_dir}/.git") endwhile() - # check if this is a submodule + set(${_git_dir_var} + "${git_dir}" + PARENT_SCOPE) +endfunction() + +function(get_git_head_revision _refspecvar _hashvar) + _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) + + if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR") + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE) + else() + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE) + endif() + if(NOT "${GIT_DIR}" STREQUAL "") + file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" + "${GIT_DIR}") + if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) + # We've gone above the CMake root dir. + set(GIT_DIR "") + endif() + endif() + if("${GIT_DIR}" STREQUAL "") + set(${_refspecvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + set(${_hashvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # Check if the current source dir is a git submodule or a worktree. + # In both cases .git is a file instead of a directory. + # if(NOT IS_DIRECTORY ${GIT_DIR}) - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + # The following git command will return a non empty string that + # points to the super project working tree if the current + # source dir is inside a git submodule. + # Otherwise the command will return an empty string. + # + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse + --show-superproject-working-tree + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" STREQUAL "") + # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE + ${submodule}) + string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} + ABSOLUTE) + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + else() + # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree + file(READ ${GIT_DIR} worktree_ref) + # The .git directory contains a path to the worktree information directory + # inside the parent git repo of the worktree. + # + string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir + ${worktree_ref}) + string(STRIP ${git_worktree_dir} git_worktree_dir) + _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) + set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") + endif() + else() + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") endif() set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") if(NOT EXISTS "${GIT_DATA}") file(MAKE_DIRECTORY "${GIT_DATA}") endif() - if(NOT EXISTS "${GIT_DIR}/HEAD") + if(NOT EXISTS "${HEAD_SOURCE_FILE}") return() endif() set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" - @ONLY) + "${GIT_DATA}/grabRef.cmake" @ONLY) include("${GIT_DATA}/grabRef.cmake") - set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) - set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) + set(${_refspecvar} + "${HEAD_REF}" + PARENT_SCOPE) + set(${_hashvar} + "${HEAD_HASH}" + PARENT_SCOPE) endfunction() function(git_describe _var) @@ -86,45 +178,107 @@ function(git_describe _var) endif() get_git_head_revision(refspec hash) if(NOT GIT_FOUND) - set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) return() endif() if(NOT hash) - set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) return() endif() # TODO sanitize #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") #endif() #message(STATUS "Arguments to execute_process: ${ARGN}") - execute_process(COMMAND - "${GIT_EXECUTABLE}" - describe - ${hash} - ${ARGN} - WORKING_DIRECTORY - "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE - res - OUTPUT_VARIABLE - out - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT res EQUAL 0) set(out "${out}-${res}-NOTFOUND") endif() - set(${_var} "${out}" PARENT_SCOPE) + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_describe_working_tree _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) endfunction() function(git_get_exact_tag _var) git_describe(out --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} + "CLEAN" + PARENT_SCOPE) + else() + set(${_var} + "DIRTY" + PARENT_SCOPE) + endif() endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in index 04db9a8e..116efc4e 100644 --- a/cmake/GetGitRevisionDescription.cmake.in +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -8,10 +8,12 @@ # http://academic.cleardefinition.com # Iowa State University HCI Graduate Program/VRAC # -# Copyright Iowa State University 2009-2010. +# Copyright 2009-2012, Iowa State University +# Copyright 2011-2015, Contributors # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +# SPDX-License-Identifier: BSL-1.0 set(HEAD_HASH) @@ -19,23 +21,23 @@ file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) if(HEAD_CONTENTS MATCHES "ref") - # named branch - string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") - if(EXISTS "@GIT_DIR@/${HEAD_REF}") - configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - else() - configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) - file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) - if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") - set(HEAD_HASH "${CMAKE_MATCH_1}") - endif() - endif() + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() else() - # detached HEAD - configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) endif() if(NOT HEAD_HASH) - file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) - string(STRIP "${HEAD_HASH}" HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) endif() diff --git a/launcher/Application.cpp b/launcher/Application.cpp index f8c93259..2bd91fd7 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -711,9 +711,20 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("CloseAfterLaunch", false); m_settings->registerSetting("QuitAfterGameStop", false); - // Custom MSA credentials + // Custom Microsoft Authentication Client ID m_settings->registerSetting("MSAClientIDOverride", ""); - m_settings->registerSetting("CFKeyOverride", ""); + + // Custom Flame API Key + { + m_settings->registerSetting("CFKeyOverride", ""); + m_settings->registerSetting("FlameKeyOverride", ""); + + QString flameKey = m_settings->get("CFKeyOverride").toString(); + + if (!flameKey.isEmpty()) + m_settings->set("FlameKeyOverride", flameKey); + m_settings->reset("CFKeyOverride"); + } m_settings->registerSetting("UserAgentOverride", ""); // Init page provider @@ -1553,6 +1564,16 @@ shared_qobject_ptr<Meta::Index> Application::metadataIndex() return m_metadataIndex; } +Application::Capabilities Application::currentCapabilities() +{ + Capabilities c; + if (!getMSAClientID().isEmpty()) + c |= SupportsMSA; + if (!getFlameAPIKey().isEmpty()) + c |= SupportsFlame; + return c; +} + QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { @@ -1581,14 +1602,14 @@ QString Application::getMSAClientID() return BuildConfig.MSA_CLIENT_ID; } -QString Application::getCurseKey() +QString Application::getFlameAPIKey() { - QString keyOverride = m_settings->get("CFKeyOverride").toString(); + QString keyOverride = m_settings->get("FlameKeyOverride").toString(); if (!keyOverride.isEmpty()) { return keyOverride; } - return BuildConfig.CURSEFORGE_API_KEY; + return BuildConfig.FLAME_API_KEY; } QString Application::getUserAgent() diff --git a/launcher/Application.h b/launcher/Application.h index e3b4fced..019c3c3d 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -90,6 +90,14 @@ public: Initialized }; + enum Capability { + None = 0, + + SupportsMSA = 1 << 0, + SupportsFlame = 1 << 1, + }; + Q_DECLARE_FLAGS(Capabilities, Capability) + public: Application(int &argc, char **argv); virtual ~Application(); @@ -154,6 +162,8 @@ public: shared_qobject_ptr<Meta::Index> metadataIndex(); + Capabilities currentCapabilities(); + /*! * Finds and returns the full path to a jar file. * Returns a null-string if it could not be found. @@ -161,7 +171,7 @@ public: QString getJarPath(QString jarFile); QString getMSAClientID(); - QString getCurseKey(); + QString getFlameAPIKey(); QString getUserAgent(); QString getUserAgentUncached(); diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index 3061e32e..e6a6adcc 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -118,8 +118,9 @@ void Download::executeTask() } request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); - if (request.url().host().contains("api.curseforge.com")) { - request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); + if (APPLICATION->currentCapabilities() & Application::SupportsFlame + && request.url().host().contains("api.curseforge.com")) { + request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8()); }; QNetworkReply* rep = m_network->get(request); diff --git a/launcher/net/Download.h b/launcher/net/Download.h index 20932944..1d264381 100644 --- a/launcher/net/Download.h +++ b/launcher/net/Download.h @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/net/Upload.cpp b/launcher/net/Upload.cpp index c9942a8d..12dd1e78 100644 --- a/launcher/net/Upload.cpp +++ b/launcher/net/Upload.cpp @@ -1,6 +1,38 @@ -// -// Created by timoreo on 20/05/22. -// +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "Upload.h" @@ -174,8 +206,9 @@ namespace Net { } request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); - if (request.url().host().contains("api.curseforge.com")) { - request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); + if (APPLICATION->currentCapabilities() & Application::SupportsFlame + && request.url().host().contains("api.curseforge.com")) { + request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8()); } //TODO other types of post requests ? request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); diff --git a/launcher/net/Upload.h b/launcher/net/Upload.h index ee784c6e..56687a31 100644 --- a/launcher/net/Upload.h +++ b/launcher/net/Upload.h @@ -1,3 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln <flowlnlnln@gmail.com> + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 "NetAction.h" diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index f01c9c07..e4fc3ecc 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -1,9 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #include "ModDownloadDialog.h" #include <BaseVersion.h> #include <icons/IconList.h> #include <InstanceList.h> +#include "Application.h" #include "ProgressDialog.h" #include "ReviewMessageBox.h" @@ -100,13 +119,13 @@ void ModDownloadDialog::accept() QList<BasePage *> ModDownloadDialog::getPages() { - modrinthPage = new ModrinthModPage(this, m_instance); - flameModPage = new FlameModPage(this, m_instance); - return - { - modrinthPage, - flameModPage - }; + QList<BasePage *> pages; + + pages.append(new ModrinthModPage(this, m_instance)); + if (APPLICATION->currentCapabilities() & Application::SupportsFlame) + pages.append(new FlameModPage(this, m_instance)); + + return pages; } void ModDownloadDialog::addSelectedMod(const QString& name, ModDownloadTask* task) diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 5c565ad3..1fa1f058 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -1,3 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #pragma once #include <QDialog> @@ -48,9 +66,6 @@ private: QDialogButtonBox * m_buttons = nullptr; QVBoxLayout *m_verticalLayout = nullptr; - - ModrinthModPage *modrinthPage = nullptr; - FlameModPage *flameModPage = nullptr; QHash<QString, ModDownloadTask*> modTask; BaseInstance *m_instance; }; diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 5b8ecc5b..35bba9be 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -150,20 +150,21 @@ void NewInstanceDialog::accept() QList<BasePage *> NewInstanceDialog::getPages() { + QList<BasePage *> pages; + importPage = new ImportPage(this); - flamePage = new FlamePage(this); - auto technicPage = new TechnicPage(this); - return - { - new VanillaPage(this), - importPage, - new AtlPage(this), - flamePage, - new FtbPage(this), - new LegacyFTB::Page(this), - new ModrinthPage(this), - technicPage - }; + + pages.append(new VanillaPage(this)); + pages.append(importPage); + pages.append(new AtlPage(this)); + if (APPLICATION->currentCapabilities() & Application::SupportsFlame) + pages.append(new FlamePage(this)); + pages.append(new FtbPage(this)); + pages.append(new LegacyFTB::Page(this)); + pages.append(new ModrinthPage(this)); + pages.append(new TechnicPage(this)); + + return pages; } QString NewInstanceDialog::dialogTitle() diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index ef74634e..a3c8cd1c 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * - * 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 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. * - * http://www.apache.org/licenses/LICENSE-2.0 + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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 @@ -69,7 +89,6 @@ private: QString InstIconKey; ImportPage *importPage = nullptr; - FlamePage *flamePage = nullptr; std::unique_ptr<InstanceTask> creationTask; bool importIcon = false; diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index b889e6f7..e3d30475 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -40,8 +40,10 @@ #include <QMessageBox> #include <QFileDialog> +#include <QRegularExpression> #include <QStandardPaths> #include <QTabBar> +#include <QValidator> #include <QVariant> #include "settings/SettingsObject.h" @@ -63,6 +65,10 @@ APIPage::APIPage(QWidget *parent) : }; static QRegularExpression validUrlRegExp("https?://.+"); + static QRegularExpression validMSAClientID(QRegularExpression::anchoredPattern( + "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")); + static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern( + "\\$2[ayb]\\$.{56}")); ui->setupUi(this); @@ -75,6 +81,8 @@ APIPage::APIPage(QWidget *parent) : // This function needs to be called even when the ComboBox's index is still in its default state. updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry)); + ui->msaClientID->setValidator(new QRegularExpressionValidator(validMSAClientID, ui->msaClientID)); + ui->flameKey->setValidator(new QRegularExpressionValidator(validFlameKey, ui->flameKey)); ui->metaURL->setPlaceholderText(BuildConfig.META_URL); ui->userAgentLineEdit->setPlaceholderText(BuildConfig.USER_AGENT); @@ -137,8 +145,8 @@ void APIPage::loadSettings() ui->msaClientID->setText(msaClientID); QString metaURL = s->get("MetaURLOverride").toString(); ui->metaURL->setText(metaURL); - QString curseKey = s->get("CFKeyOverride").toString(); - ui->curseKey->setText(curseKey); + QString flameKey = s->get("FlameKeyOverride").toString(); + ui->flameKey->setText(flameKey); QString customUserAgent = s->get("UserAgentOverride").toString(); ui->userAgentLineEdit->setText(customUserAgent); } @@ -167,8 +175,8 @@ void APIPage::applySettings() } s->set("MetaURLOverride", metaURL); - QString curseKey = ui->curseKey->text(); - s->set("CFKeyOverride", curseKey); + QString flameKey = ui->flameKey->text(); + s->set("FlameKeyOverride", flameKey); s->set("UserAgentOverride", ui->userAgentLineEdit->text()); } diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 5327771c..1ae788c7 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -196,7 +196,7 @@ </widget> </item> <item> - <widget class="QGroupBox" name="groupBox_curse"> + <widget class="QGroupBox" name="groupBox_flame"> <property name="enabled"> <bool>true</bool> </property> @@ -214,7 +214,7 @@ <item row="2" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> - <string>Enter a custom API Key for CurseForge here. </string> + <string>Enter a custom API Key for CurseForge here.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -228,7 +228,7 @@ </widget> </item> <item row="1" column="0"> - <widget class="QLineEdit" name="curseKey"> + <widget class="QLineEdit" name="flameKey"> <property name="enabled"> <bool>true</bool> </property> diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index a608771e..fcc43add 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -96,7 +96,7 @@ AccountListPage::AccountListPage(QWidget *parent) updateButtonStates(); // Xbox authentication won't work without a client identifier, so disable the button if it is missing - if (APPLICATION->getMSAClientID().isEmpty()) { + if (~APPLICATION->currentCapabilities() & Application::SupportsMSA) { ui->actionAddMicrosoft->setVisible(false); ui->actionAddMicrosoft->setToolTip(tr("No Microsoft Authentication client ID was set.")); } diff --git a/launcher/ui/pages/modplatform/ImportPage.ui b/launcher/ui/pages/modplatform/ImportPage.ui index 77bc5da5..0a50e871 100644 --- a/launcher/ui/pages/modplatform/ImportPage.ui +++ b/launcher/ui/pages/modplatform/ImportPage.ui @@ -40,7 +40,7 @@ <item> <widget class="QLabel" name="label_5"> <property name="text"> - <string>- Curseforge modpacks (ZIP)</string> + <string>- CurseForge modpacks (ZIP)</string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index 8d835322..b1ba89df 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -1,3 +1,13 @@ +if(UNIX) + find_package(PkgConfig) + if(PkgConfig_FOUND) + pkg_search_module(SCDOC scdoc) + if(SCDOC_FOUND) + pkg_get_variable(SCDOC_SCDOC scdoc scdoc) + endif() + endif() +endif() + set(Launcher_CommonName "PolyMC") set(Launcher_Copyright "PolyMC Contributors\\n© 2012-2021 MultiMC Contributors") @@ -12,7 +22,6 @@ set(Launcher_DesktopFileName "org.polymc.PolyMC.desktop" PARENT_SCOPE) set(Launcher_Desktop "program_info/org.polymc.PolyMC.desktop" PARENT_SCOPE) set(Launcher_MetaInfo "program_info/org.polymc.PolyMC.metainfo.xml" PARENT_SCOPE) -set(Launcher_ManPage "program_info/polymc.6.txt" PARENT_SCOPE) set(Launcher_SVG "program_info/org.polymc.PolyMC.svg" PARENT_SCOPE) set(Launcher_Branding_ICNS "program_info/polymc.icns" PARENT_SCOPE) set(Launcher_Branding_ICO "program_info/polymc.ico") @@ -28,3 +37,15 @@ configure_file(polymc.rc.in polymc.rc @ONLY) configure_file(polymc.manifest.in polymc.manifest @ONLY) configure_file(polymc.ico polymc.ico COPYONLY) configure_file(win_install.nsi.in win_install.nsi @ONLY) + +if(SCDOC_FOUND) + set(in_scd "${CMAKE_CURRENT_SOURCE_DIR}/polymc.6.scd") + set(out_man "${CMAKE_CURRENT_BINARY_DIR}/polymc.6") + add_custom_command( + DEPENDS "${in_scd}" + OUTPUT "${out_man}" + COMMAND ${SCDOC_SCDOC} < "${in_scd}" > "${out_man}" + ) + add_custom_target(man ALL DEPENDS ${out_man}) + set(Launcher_ManPage "program_info/polymc.6" PARENT_SCOPE) +endif() diff --git a/program_info/polymc.6.scd b/program_info/polymc.6.scd new file mode 100644 index 00000000..f0628cc9 --- /dev/null +++ b/program_info/polymc.6.scd @@ -0,0 +1,61 @@ +polymc(6) + + +# NAME + +polymc - a launcher and instance manager for Minecraft. + + +# SYNOPSIS + +*polymc* [OPTIONS...] + + +# DESCRIPTION + +PolyMC is a custom launcher for Minecraft that allows you to easily manage +multiple installations of Minecraft at once. It also allows you to easily +install and remove mods by simply dragging and dropping. +Here are the current features of PolyMC. + +# OPTIONS + +*-d, --dir*=DIRECTORY + Use DIRECTORY as the PolyMC root. + +*-l, --launch*=INSTANCE_ID + Launch the instance specified by INSTANCE_ID. + +*--alive* + Write a small 'live.check' file after PolyMC starts. + +*-h, --help* + Display help text and exit. + +*-v, --version* + Display program version and exit. + +*-a, --profile*=PROFILE + Use the account specified by PROFILE (only valid in combination with --launch). + +# EXIT STATUS + +*0* + Success + +*1* + Failure (syntax or usage error; configuration error; unexpected error). + +# BUGS + +https://github.com/PolyMC/PolyMC/issues + +# RESOURCES + +GitHub: https://github.com/PolyMC/PolyMC + +Main website: https://polymc.org + +# AUTHORS + +PolyMC Contributors diff --git a/program_info/polymc.6.txt b/program_info/polymc.6.txt deleted file mode 100644 index 8f126cce..00000000 --- a/program_info/polymc.6.txt +++ /dev/null @@ -1,64 +0,0 @@ -POLYMC(1) -========== -:doctype: manpage - - -NAME ----- -polymc - a launcher and instance manager for Minecraft. - - -SYNOPSIS --------- -*polymc* ['OPTIONS'] - - -DESCRIPTION ------------ -PolyMC is a custom launcher for Minecraft that allows you to easily manage -multiple installations of Minecraft at once. It also allows you to easily -install and remove mods by simply dragging and dropping. -Here are the current features of PolyMC. - -OPTIONS -------- -*-d, --dir*='DIRECTORY':: - Use 'DIRECTORY' as the PolyMC root. - -*-l, --launch*='INSTANCE_ID':: - Launch the instance specified by 'INSTANCE_ID'. - -*--alive*:: - Write a small 'live.check' file after PolyMC starts. - -*-h, --help*:: - Display help text and exit. - -*-v, --version*:: - Display program version and exit. -*-a, --profile*='PROFILE':: - Use the account specified by 'PROFILE' (only valid in combination with --launch). - -EXIT STATUS ------------ -*0*:: - Success - -*1*:: - Failure (syntax or usage error; configuration error; unexpected error). - -BUGS ----- -<https://github.com/PolyMC/PolyMC/issues> - -RESOURCES ---------- -GitHub: <https://github.com/PolyMC/PolyMC> - -Main website: <https://polymc.org> - -AUTHORS -------- -PolyMC Contributors - -// vim: syntax=asciidoc |