diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 247675fc..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -open_collective: polymc diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ab3c8a29..24ae5b7a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,8 +5,6 @@ body: - type: markdown attributes: value: | - If you need help with running Minecraft, please visit us on our Discord before making a bug report. - Before submitting a bug report, please make sure you have read this *entire* form, and that: * You have read the [PolyMC wiki](https://polymc.org/wiki/) and it has not answered your question. * Your bug is not caused by Minecraft or any mods you have installed. @@ -25,15 +23,15 @@ body: - Other - type: textarea attributes: - label: Version of PolyMC - description: The version of PolyMC used in the bug report. - placeholder: PolyMC 1.4.1 + label: Version of PollyMC + description: The version of PollyMC used in the bug report. + placeholder: PollyMC 1.4.1 validations: required: true - type: textarea attributes: label: Version of Qt - description: The version of Qt used in the bug report. You can find it in Help -> About PolyMC -> About Qt. + description: The version of Qt used in the bug report. You can find it in Help -> About PollyMC -> About Qt. placeholder: Qt 6.3.0 validations: required: true @@ -41,14 +39,14 @@ body: attributes: label: Description of bug description: What did you expect to happen, what happened, and why is it incorrect? - placeholder: The cat button should show a cat, but it showed a dog instead! + placeholder: The parrot button should show a parrot, but it showed a cat instead! validations: required: true - type: textarea attributes: label: Steps to reproduce description: A bulleted list, or an exported instance if relevant. - placeholder: "* Press the cat button" + placeholder: "* Press the parrot button" validations: required: true - type: textarea diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 932d0c8f..0086358d 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1 @@ blank_issues_enabled: true -contact_links: - - name: PolyMC Matrix Support Room - url: https://matrix.to/#/#support:polymc.org - about: Please ask for support here before opening an issue. diff --git a/.github/ISSUE_TEMPLATE/rfc.yml b/.github/ISSUE_TEMPLATE/rfc.yml index 0a40d01d..323aa9b3 100644 --- a/.github/ISSUE_TEMPLATE/rfc.yml +++ b/.github/ISSUE_TEMPLATE/rfc.yml @@ -6,38 +6,38 @@ body: - type: markdown attributes: value: | - ### Use this form to suggest a larger change for PolyMC. + ### Use this form to suggest a larger change for PollyMC. - type: textarea attributes: label: Goal description: Short description, 1-2 sentences. - placeholder: Remove the cat from the launcher. + placeholder: Remove the parrot from the launcher. validations: required: true - type: textarea attributes: label: Motivation description: | - Introduce the topic. If this is a not-well-known section of PolyMC, a detailed explanation of the background is recommended. + Introduce the topic. If this is a not-well-known section of PollyMC, a detailed explanation of the background is recommended. Some example points of discussion: - What specific problems are you facing right now that you're trying to address? - Are there any previous discussions? Link to them and summarize them (don't force your readers to read them though!). - Is there any precedent set by other software? If so, link to resources. - placeholder: I don't like cats. I think many users also don't like cats. + placeholder: I don't like parrots. I think many users also don't like parrots. validations: required: true - type: textarea attributes: label: Specification description: A concrete, thorough explanation of what is being planned. - placeholder: Remove the cat button and all references to the cat from the codebase. Including resource files. + placeholder: Remove the parrot button and all references to the parrot from the codebase. Including resource files. validations: required: true - type: textarea attributes: label: Drawbacks description: Carefully consider every possible objection and issue with your proposal. This section should be updated as feedback comes in from discussion. - placeholder: Some users might like cats. + placeholder: Some users might like parrots. validations: required: true - type: textarea @@ -47,14 +47,14 @@ body: Are there any portions of your proposal which need to be discussed with the community before the RFC can proceed? Be careful here -- an RFC with a lot of remaining questions is likely to be stalled. If your RFC is mostly unresolved questions and not too much substance, it may not be ready. - placeholder: Do a lot of users care about the cat? + placeholder: Do a lot of users care about the parrot? validations: required: true - type: textarea attributes: label: Alternatives Considered description: A list of alternatives, that have been considered and offer equal or similar features to the proposed change. - placeholder: Maybe the cat could be replaced with an axolotl? + placeholder: Maybe the parrot could be replaced with a dog? validations: required: true - type: checkboxes diff --git a/.github/ISSUE_TEMPLATE/suggestion.yml b/.github/ISSUE_TEMPLATE/suggestion.yml index 48f157b3..69d34ea9 100644 --- a/.github/ISSUE_TEMPLATE/suggestion.yml +++ b/.github/ISSUE_TEMPLATE/suggestion.yml @@ -5,26 +5,26 @@ body: - type: markdown attributes: value: | - ### Use this form to suggest a feature for PolyMC. + ### Use this form to suggest a feature for PollyMC. - type: input attributes: label: Role - description: In what way do you use PolyMC that needs this feature? + description: In what way do you use PollyMC that needs this feature? placeholder: I play modded Minecraft. validations: required: true - type: input attributes: label: Suggestion - description: What do you want PolyMC to do? - placeholder: I want the cat button to meow. + description: What do you want PollyMC to do? + placeholder: I want the parrot button to squawk. validations: required: true - type: input attributes: label: Benefit - description: Why do you need PolyMC to do this? - placeholder: so that I can always hear a cat when I need to. + description: Why do you need PollyMC to do this? + placeholder: so that I can always hear a parrot when I need to. validations: required: true - type: checkboxes diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 434c5775..e47eb983 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -219,9 +219,9 @@ jobs: cmake --install ${{ env.BUILD_DIR }} cd ${{ env.INSTALL_DIR }} - chmod +x "PolyMC.app/Contents/MacOS/polymc" - sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PolyMC.app/Contents/MacOS/polymc" - tar -czf ../PolyMC.tar.gz * + chmod +x "PollyMC.app/Contents/MacOS/pollymc" + sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PollyMC.app/Contents/MacOS/pollymc" + tar -czf ../PollyMC.tar.gz * - name: Make Sparkle signature (macOS) if: runner.os == 'macOS' @@ -229,7 +229,7 @@ jobs: if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then brew install openssl@3 echo '${{ secrets.SPARKLE_ED25519_KEY }}' > ed25519-priv.pem - signature=$(/usr/local/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/PolyMC.tar.gz -inkey ed25519-priv.pem | openssl base64 | tr -d \\n) + signature=$(/usr/local/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/PollyMC.tar.gz -inkey ed25519-priv.pem | openssl base64 | tr -d \\n) rm ed25519-priv.pem cat >> $GITHUB_STEP_SUMMARY << EOF ### Artifact Information :information_source: @@ -273,7 +273,7 @@ jobs: cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }} cd ${{ env.INSTALL_DIR }} - tar --owner root --group root -czf ../PolyMC.tar.gz * + tar --owner root --group root -czf ../PollyMC.tar.gz * - name: Package (Linux, portable) if: runner.os == 'Linux' @@ -282,7 +282,7 @@ jobs: cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable cd ${{ env.INSTALL_PORTABLE_DIR }} - tar -czf ../PolyMC-portable.tar.gz * + tar -czf ../PollyMC-portable.tar.gz * - name: Package AppImage (Linux) if: runner.os == 'Linux' && matrix.qt_ver != 5 @@ -290,7 +290,7 @@ jobs: run: | cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_APPIMAGE_DIR }}/usr - export OUTPUT="PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage" + export OUTPUT="PollyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage" chmod +x linuxdeploy-*.AppImage @@ -301,7 +301,7 @@ jobs: cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk - cp -r /home/runner/work/PolyMC/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines + cp -r /home/runner/work/PollyMC/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/ cp /usr/lib/x86_64-linux-gnu/libssl.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}//usr/lib/ @@ -313,7 +313,7 @@ jobs: LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib" export LD_LIBRARY_PATH - ./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.polymc.PolyMC.svg + ./linuxdeploy-x86_64.AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.fn2006.PollyMC.svg ## # UPLOAD BUILDS @@ -323,63 +323,63 @@ jobs: if: runner.os == 'macOS' uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC.tar.gz + name: PollyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC.tar.gz - name: Upload binary zip (Windows) if: runner.os == 'Windows' uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }} + name: PollyMC-${{ matrix.name }}-${{ env.VERSION }}-${{ inputs.build_type }} path: ${{ env.INSTALL_DIR }}/** - name: Upload binary zip (Windows, portable) if: runner.os == 'Windows' uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ matrix.name }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} + name: PollyMC-${{ matrix.name }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} path: ${{ env.INSTALL_PORTABLE_DIR }}/** - name: Upload installer (Windows) if: runner.os == 'Windows' uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC-Setup.exe + name: PollyMC-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC-Setup.exe - name: Upload binary tarball (Linux, Qt 5) if: runner.os == 'Linux' && matrix.qt_ver != 6 uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC.tar.gz + name: PollyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC.tar.gz - name: Upload binary tarball (Linux, portable, Qt 5) if: runner.os == 'Linux' && matrix.qt_ver != 6 uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC-portable.tar.gz + name: PollyMC-${{ runner.os }}-Portable-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC-portable.tar.gz - name: Upload binary tarball (Linux, Qt 6) if: runner.os == 'Linux' && matrix.qt_ver !=5 uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-Qt6-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC.tar.gz + name: PollyMC-${{ runner.os }}-Qt6-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC.tar.gz - name: Upload binary tarball (Linux, portable, Qt 6) if: runner.os == 'Linux' && matrix.qt_ver != 5 uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }} - path: PolyMC-portable.tar.gz + name: PollyMC-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }} + path: PollyMC-portable.tar.gz - name: Upload AppImage (Linux) if: runner.os == 'Linux' && matrix.qt_ver != 5 uses: actions/upload-artifact@v3 with: - name: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage - path: PolyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage + name: PollyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage + path: PollyMC-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage diff --git a/.github/workflows/trigger_builds.yml b/.github/workflows/trigger_builds.yml index 55b4fdd4..ee9eb4ea 100644 --- a/.github/workflows/trigger_builds.yml +++ b/.github/workflows/trigger_builds.yml @@ -11,7 +11,6 @@ on: - '**.nix' - 'packages/**' - '.github/ISSUE_TEMPLATE/**' - - '.markdownlint**' pull_request: paths-ignore: - '**.md' @@ -20,7 +19,6 @@ on: - '**.nix' - 'packages/**' - '.github/ISSUE_TEMPLATE/**' - - '.markdownlint**' workflow_dispatch: jobs: diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 45ef7281..af5c2137 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@v3 with: submodules: 'true' - path: 'PolyMC-source' + path: 'PollyMC-source' - name: Download artifacts uses: actions/download-artifact@v3 - name: Grab and store version @@ -34,25 +34,25 @@ jobs: echo "VERSION=$tag_name" >> $GITHUB_ENV - name: Package artifacts properly run: | - mv ${{ github.workspace }}/PolyMC-source PolyMC-${{ env.VERSION }} - mv PolyMC-Linux-Qt6-Portable*/PolyMC-portable.tar.gz PolyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz - mv PolyMC-Linux-Qt6*/PolyMC.tar.gz PolyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz - mv PolyMC-Linux-Portable*/PolyMC-portable.tar.gz PolyMC-Linux-Portable-${{ env.VERSION }}.tar.gz - mv PolyMC-Linux*/PolyMC.tar.gz PolyMC-Linux-${{ env.VERSION }}.tar.gz - mv PolyMC-*.AppImage/PolyMC-*.AppImage PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage - mv PolyMC-macOS*/PolyMC.tar.gz PolyMC-macOS-${{ env.VERSION }}.tar.gz + mv ${{ github.workspace }}/PollyMC-source PollyMC-${{ env.VERSION }} + mv PollyMC-Linux-Qt6-Portable*/PollyMC-portable.tar.gz PollyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz + mv PollyMC-Linux-Qt6*/PollyMC.tar.gz PollyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz + mv PollyMC-Linux-Portable*/PollyMC-portable.tar.gz PollyMC-Linux-Portable-${{ env.VERSION }}.tar.gz + mv PollyMC-Linux*/PollyMC.tar.gz PollyMC-Linux-${{ env.VERSION }}.tar.gz + mv PollyMC-*.AppImage/PollyMC-*.AppImage PollyMC-Linux-${{ env.VERSION }}-x86_64.AppImage + mv PollyMC-macOS*/PollyMC.tar.gz PollyMC-macOS-${{ env.VERSION }}.tar.gz - tar -czf PolyMC-${{ env.VERSION }}.tar.gz PolyMC-${{ env.VERSION }} + tar -czf PollyMC-${{ env.VERSION }}.tar.gz PollyMC-${{ env.VERSION }} - for d in PolyMC-Windows-*; do + for d in PollyMC-Windows-*; do cd "${d}" || continue LEGACY="$(echo -n ${d} | grep -o Legacy || true)" INST="$(echo -n ${d} | grep -o Setup || true)" PORT="$(echo -n ${d} | grep -o Portable || true)" - NAME="PolyMC-Windows" + NAME="PollyMC-Windows" test -z "${LEGACY}" || NAME="${NAME}-Legacy" test -z "${PORT}" || NAME="${NAME}-Portable" - test -z "${INST}" || mv PolyMC-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe + test -z "${INST}" || mv PollyMC-*.exe ../${NAME}-Setup-${{ env.VERSION }}.exe test -n "${INST}" || zip -r -9 "../${NAME}-${{ env.VERSION }}.zip" * cd .. done @@ -64,20 +64,20 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} - name: PolyMC ${{ env.VERSION }} + name: PollyMC ${{ env.VERSION }} draft: true prerelease: false files: | - PolyMC-Linux-${{ env.VERSION }}.tar.gz - PolyMC-Linux-Portable-${{ env.VERSION }}.tar.gz - PolyMC-Linux-${{ env.VERSION }}-x86_64.AppImage - PolyMC-Windows-Legacy-${{ env.VERSION }}.zip - PolyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz - PolyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz - PolyMC-Windows-Legacy-Portable-${{ env.VERSION }}.zip - PolyMC-Windows-Legacy-Setup-${{ env.VERSION }}.exe - PolyMC-Windows-${{ env.VERSION }}.zip - PolyMC-Windows-Portable-${{ env.VERSION }}.zip - PolyMC-Windows-Setup-${{ env.VERSION }}.exe - PolyMC-macOS-${{ env.VERSION }}.tar.gz - PolyMC-${{ env.VERSION }}.tar.gz + PollyMC-Linux-${{ env.VERSION }}.tar.gz + PollyMC-Linux-Portable-${{ env.VERSION }}.tar.gz + PollyMC-Linux-${{ env.VERSION }}-x86_64.AppImage + PollyMC-Windows-Legacy-${{ env.VERSION }}.zip + PollyMC-Linux-Qt6-${{ env.VERSION }}.tar.gz + PollyMC-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz + PollyMC-Windows-Legacy-Portable-${{ env.VERSION }}.zip + PollyMC-Windows-Legacy-Setup-${{ env.VERSION }}.exe + PollyMC-Windows-${{ env.VERSION }}.zip + PollyMC-Windows-Portable-${{ env.VERSION }}.zip + PollyMC-Windows-Setup-${{ env.VERSION }}.exe + PollyMC-macOS-${{ env.VERSION }}.tar.gz + PollyMC-${{ env.VERSION }}.tar.gz diff --git a/CMakeLists.txt b/CMakeLists.txt index 7100ab1b..e9f838a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,19 +99,19 @@ set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch L set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") # Bug tracker URL -set(Launcher_BUG_TRACKER_URL "https://github.com/PolyMC/PolyMC/issues" CACHE STRING "URL for the bug tracker.") +set(Launcher_BUG_TRACKER_URL "https://github.com/fn2006/PollyMC/issues" CACHE STRING "URL for the bug tracker.") # Translations Platform URL set(Launcher_TRANSLATIONS_URL "https://hosted.weblate.org/projects/polymc/polymc/" CACHE STRING "URL for the translations platform.") # Matrix Space -set(Launcher_MATRIX_URL "https://matrix.to/#/#polymc:matrix.org" CACHE STRING "URL to the Matrix Space") +set(Launcher_MATRIX_URL "" CACHE STRING "URL to the Matrix Space") # Discord URL -set(Launcher_DISCORD_URL "https://discord.gg/Z52pwxWCHP" CACHE STRING "URL for the Discord guild.") +set(Launcher_DISCORD_URL "" CACHE STRING "URL for the Discord guild.") # Subreddit URL -set(Launcher_SUBREDDIT_URL "https://www.reddit.com/r/PolyMCLauncher/" CACHE STRING "URL for the subreddit.") +set(Launcher_SUBREDDIT_URL "" CACHE STRING "URL for the subreddit.") # Builds set(Launcher_FORCE_BUNDLED_LIBS OFF CACHE BOOL "Prevent using system libraries, if they are available as submodules") @@ -126,12 +126,12 @@ set(Launcher_QT_VERSION_MAJOR "5" CACHE STRING "Major Qt version to build agains # By using this key in your builds you accept the terms of use laid down in # https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use -set(Launcher_MSA_CLIENT_ID "549033b2-1532-4d4e-ae77-1bbaa46f9d74" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application") +set(Launcher_MSA_CLIENT_ID "" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application") # 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 "API key for the CurseForge platform") +set(Launcher_CURSEFORGE_API_KEY "" CACHE STRING "API key for the CurseForge platform") #### Check the current Git commit and branch @@ -194,7 +194,7 @@ endif() ####################################### Program Info ####################################### -set(Launcher_APP_BINARY_NAME "polymc" CACHE STRING "Name of the Launcher binary") +set(Launcher_APP_BINARY_NAME "pollymc" CACHE STRING "Name of the Launcher binary") add_subdirectory(program_info) ####################################### Install layout ####################################### diff --git a/README.md b/README.md index 6ff868e0..8e270d7a 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,13 @@

-PolyMC logo -PolyMC logo +PollyMC logo +PollyMC logo

-PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity. +PollyMC is a **fork** of PolyMC and is not endorsed by or affiliated with the PolyMC project. +If you have any problems open an issue here, do not bug the PolyMC maintainers. -This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. -If you want to read about why this fork was created, check out [our FAQ page](https://polymc.org/wiki/overview/faq/). -
+Binaries can be found in releases. -# Installation +Workaround for downloading from CurseForge and FTB not working [here](https://github.com/fn2006/PollyMC/wiki/CurseForge-Workaround). -- All downloads and instructions for PolyMC can be found [here](https://polymc.org/download/) -- Last build status: - -## Development Builds - -There are per-commit development builds available [here](https://github.com/PolyMC/PolyMC/actions). These have debug information in the binaries, so their file sizes are relatively larger. -Portable builds are provided for AppImage on Linux, Windows, and macOS. - -For Debian and Arch, you can use these packages for the latest development versions: -[![polymc-git](https://img.shields.io/badge/aur-polymc--git-blue)](https://aur.archlinux.org/packages/polymc-git/) -[![polymc-git](https://img.shields.io/badge/mpr-polymc--git-orange)](https://mpr.makedeb.org/packages/polymc-git) -For flatpak, you can use [flathub-beta](https://discourse.flathub.org/t/how-to-use-flathub-beta/2111) - -# Help & Support - -Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server. - -[![PolyMC Discord](https://img.shields.io/discord/923671181020766230?label=PolyMC%20Discord)](https://discord.gg/xq7fxrgtMP) - -For people who don't want to use Discord, we have a Matrix Space which is bridged to the Discord server: - -[![PolyMC Space](https://img.shields.io/matrix/polymc:matrix.org?label=PolyMC%20space)](https://matrix.to/#/#polymc:matrix.org) - -If there are any issues with the space or you are using a client that does not support the feature here are the individual rooms: - -[![Development](https://img.shields.io/matrix/polymc-development:matrix.org?label=PolyMC%20Development)](https://matrix.to/#/#polymc-development:matrix.org) -[![Discussion](https://img.shields.io/matrix/polymc-discussion:matrix.org?label=PolyMC%20Discussion)](https://matrix.to/#/#polymc-discussion:matrix.org) -[![Github](https://img.shields.io/matrix/polymc-github:matrix.org?label=PolyMC%20Github)](https://matrix.to/#/#polymc-github:matrix.org) -[![Maintainers](https://img.shields.io/matrix/polymc-maintainers:matrix.org?label=PolyMC%20Maintainers)](https://matrix.to/#/#polymc-maintainers:matrix.org) -[![News](https://img.shields.io/matrix/polymc-news:matrix.org?label=PolyMC%20News)](https://matrix.to/#/#polymc-news:matrix.org) -[![Offtopic](https://img.shields.io/matrix/polymc-offtopic:matrix.org?label=PolyMC%20Offtopic)](https://matrix.to/#/#polymc-offtopic:matrix.org) -[![Support](https://img.shields.io/matrix/polymc-support:matrix.org?label=PolyMC%20Support)](https://matrix.to/#/#polymc-support:matrix.org) -[![Voice](https://img.shields.io/matrix/polymc-voice:matrix.org?label=PolyMC%20Voice)](https://matrix.to/#/#polymc-voice:matrix.org) - -We also have a subreddit you can post your issues and suggestions on: - -[r/PolyMCLauncher](https://www.reddit.com/r/PolyMCLauncher/) - -# Development - -If you want to contribute to PolyMC you might find it useful to join our Discord Server or Matrix Space. - -## Building - -If you want to build PolyMC yourself, check [Build Instructions](https://polymc.org/wiki/development/build-instructions/) for build instructions. - -## Translations - -The translation effort for PolyMC is hosted on [Weblate](https://hosted.weblate.org/projects/polymc/polymc/) and information about translating PolyMC is available at - -## Download information - -To modify download information or change packaging information send a pull request or issue to the website [here](https://github.com/PolyMC/polymc.github.io/tree/master/src/download). - -## Forking/Redistributing/Custom builds policy - -We don't care what you do with your fork/custom build as long as you follow the terms of the [license](LICENSE) (this is a legal responsibility), and if you made code changes rather than just packaging a custom build, please do the following as a basic courtesy: - -- Make it clear that your fork is not PolyMC and is not endorsed by or affiliated with the PolyMC project (). -- Go through [CMakeLists.txt](CMakeLists.txt) and change PolyMC's API keys to your own or set them to empty strings (`""`) to disable them (this way the program will still compile but the functionality requiring those keys will be disabled). - -If you have any questions or want any clarification on the above conditions please make an issue and ask us. - -Be aware that if you build this software without removing the provided API keys in [CMakeLists.txt](CMakeLists.txt) you are accepting the following terms and conditions: - -- [Microsoft Identity Platform Terms of Use](https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use) -- [CurseForge 3rd Party API Terms and Conditions](https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions) - -If you do not agree with these terms and conditions, then remove the associated API keys from the [CMakeLists.txt](CMakeLists.txt) file by setting them to an empty string (`""`). - -All launcher code is available under the GPL-3.0-only license. - -The logo and related assets are under the CC BY-SA 4.0 license. - -## Sponsors - -Thank you to all our generous backers over at Open Collective! Support PolyMC by [becoming a backer](https://opencollective.com/polymc). - -[![OpenCollective Backers](https://opencollective.com/polymc/backers.svg?width=890&limit=1000)](https://opencollective.com/polymc#backers) - -Also, thanks to JetBrains for providing us a few licenses for all their products, as part of their [Open Source program](https://www.jetbrains.com/opensource/). - -[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/opensource/) - -Additionally, thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), for providing M1-Macs for development purposes! - -Powered by MacStadium +To build this yourself, follow the instructions on the PolyMC website but clone this repo instead. diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c4179b49..cb3f6c8c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -881,6 +881,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_metacache->addBase("translations", QDir("translations").absolutePath()); m_metacache->addBase("icons", QDir("cache/icons").absolutePath()); m_metacache->addBase("meta", QDir("meta").absolutePath()); + m_metacache->addBase("injectors", QDir("injectors").absolutePath()); m_metacache->Load(); qDebug() << "<> Cache initialized."; } @@ -1223,7 +1224,8 @@ void Application::setIconTheme(const QString& name) QIcon Application::getThemedIcon(const QString& name) { if(name == "logo") { - return QIcon(":/org.polymc.PolyMC.svg"); + // why is this hardcoded lol + return QIcon(":/org.fn2006.PollyMC.svg"); } return QIcon::fromTheme(name); } diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index e44b98eb..360209b5 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -206,11 +206,15 @@ set(MINECRAFT_SOURCES minecraft/auth/flows/MSA.h minecraft/auth/flows/Offline.cpp minecraft/auth/flows/Offline.h + minecraft/auth/flows/Elyby.cpp + minecraft/auth/flows/Elyby.h - minecraft/auth/steps/OfflineStep.cpp - minecraft/auth/steps/OfflineStep.h minecraft/auth/steps/EntitlementsStep.cpp minecraft/auth/steps/EntitlementsStep.h + minecraft/auth/steps/ElybyProfileStep.cpp + minecraft/auth/steps/ElybyProfileStep.h + minecraft/auth/steps/ElybyStep.cpp + minecraft/auth/steps/ElybyStep.h minecraft/auth/steps/GetSkinStep.cpp minecraft/auth/steps/GetSkinStep.h minecraft/auth/steps/LauncherLoginStep.cpp @@ -223,6 +227,8 @@ set(MINECRAFT_SOURCES minecraft/auth/steps/MinecraftProfileStepMojang.h minecraft/auth/steps/MSAStep.cpp minecraft/auth/steps/MSAStep.h + minecraft/auth/steps/OfflineStep.cpp + minecraft/auth/steps/OfflineStep.h minecraft/auth/steps/XboxAuthorizationStep.cpp minecraft/auth/steps/XboxAuthorizationStep.h minecraft/auth/steps/XboxProfileStep.cpp @@ -258,6 +264,8 @@ set(MINECRAFT_SOURCES minecraft/launch/LauncherPartLaunch.h minecraft/launch/MinecraftServerTarget.cpp minecraft/launch/MinecraftServerTarget.h + minecraft/launch/InjectAuthlib.cpp + minecraft/launch/InjectAuthlib.h minecraft/launch/PrintInstanceInfo.cpp minecraft/launch/PrintInstanceInfo.h minecraft/launch/ReconstructAssets.cpp @@ -774,6 +782,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/CustomMessageBox.h ui/dialogs/EditAccountDialog.cpp ui/dialogs/EditAccountDialog.h + ui/dialogs/ElybyLoginDialog.cpp + ui/dialogs/ElybyLoginDialog.h ui/dialogs/ExportInstanceDialog.cpp ui/dialogs/ExportInstanceDialog.h ui/dialogs/IconPickerDialog.cpp @@ -924,6 +934,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/IconPickerDialog.ui ui/dialogs/MSALoginDialog.ui ui/dialogs/OfflineLoginDialog.ui + ui/dialogs/ElybyLoginDialog.ui ui/dialogs/AboutDialog.ui ui/dialogs/LoginDialog.ui ui/dialogs/EditAccountDialog.ui diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 9478b1b8..ef1fbfef 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -356,6 +356,7 @@ QStringList MinecraftInstance::extraArguments() if (!addn.isEmpty()) { list.append(addn); } + auto agents = m_components->getProfile()->getAgents(); for (auto agent : agents) { @@ -363,6 +364,13 @@ QStringList MinecraftInstance::extraArguments() agent->library()->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, getLocalLibraryPath()); list.append("-javaagent:"+jar[0]+(agent->argument().isEmpty() ? "" : "="+agent->argument())); } + + // TODO: figure out how polymc's javaagent system works and use it instead of this hack + if (m_injector) { + list.append("-javaagent:"+m_injector->javaArg); + list.append("-Dauthlibinjector.noShowServerName"); + } + return list; } @@ -978,7 +986,14 @@ shared_qobject_ptr MinecraftInstance::createLaunchTask(AuthSessionPt if(!session->demo) { process->appendStep(new ClaimAccount(pptr, session)); } + + // authlib patch + if (session->user_type == "elyby") + { + process->appendStep(new InjectAuthlib(pptr, &m_injector)); + } process->appendStep(new Update(pptr, Net::Mode::Online)); + } else { diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index d62ac655..c3c2d850 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -5,6 +5,7 @@ #include #include #include "minecraft/launch/MinecraftServerTarget.h" +#include "minecraft/launch/InjectAuthlib.h" class ModFolderModel; class ResourceFolderModel; @@ -134,6 +135,7 @@ protected: // data mutable std::shared_ptr m_texture_pack_list; mutable std::shared_ptr m_world_list; mutable std::shared_ptr m_game_options; + mutable std::shared_ptr m_injector; }; typedef std::shared_ptr MinecraftInstancePtr; diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index 44f7e256..50ca155f 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -352,6 +352,8 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { type = AccountType::Mojang; } else if (typeS == "Offline") { type = AccountType::Offline; + } else if (typeS == "Elyby") { + type = AccountType::Elyby; } else { qWarning() << "Failed to parse account data: type is not recognized."; return false; @@ -409,6 +411,9 @@ QJsonObject AccountData::saveState() const { else if (type == AccountType::Offline) { output["type"] = "Offline"; } + else if (type == AccountType::Elyby) { + output["type"] = "Elyby"; + } tokenToJSONV3(output, yggdrasilToken, "ygg"); profileToJSONV3(output, minecraftProfile, "profile"); @@ -428,14 +433,14 @@ QString AccountData::accessToken() const { } QString AccountData::clientToken() const { - if(type != AccountType::Mojang) { + if(type != AccountType::Mojang && type != AccountType::Elyby) { return QString(); } return yggdrasilToken.extra["clientToken"].toString(); } void AccountData::setClientToken(QString clientToken) { - if(type != AccountType::Mojang) { + if(type != AccountType::Mojang && type != AccountType::Elyby) { return; } yggdrasilToken.extra["clientToken"] = clientToken; @@ -449,7 +454,7 @@ void AccountData::generateClientTokenIfMissing() { } void AccountData::invalidateClientToken() { - if(type != AccountType::Mojang) { + if(type != AccountType::Mojang && type != AccountType::Elyby) { return; } yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{-}]")); @@ -473,6 +478,9 @@ QString AccountData::accountDisplayString() const { case AccountType::Mojang: { return userName(); } + case AccountType::Elyby: { + return userName(); + } case AccountType::Offline: { return QObject::tr(""); } diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index 092e1691..c11aa146 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -74,7 +74,8 @@ struct MinecraftProfile { enum class AccountType { MSA, Mojang, - Offline + Offline, + Elyby }; enum class AccountState { diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index b3b57c74..4f7f0a12 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -332,7 +332,7 @@ QVariant AccountList::data(const QModelIndex &index, int role) const } case MigrationColumn: { - if(account->isMSA() || account->isOffline()) { + if(!account->isMojang()) { return tr("N/A", "Can Migrate?"); } if (account->canMigrate()) { diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index 73d570f1..86b5c80e 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -51,6 +51,7 @@ #include "flows/MSA.h" #include "flows/Mojang.h" #include "flows/Offline.h" +#include "flows/Elyby.h" MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent) { data.internalId = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); @@ -106,6 +107,17 @@ MinecraftAccountPtr MinecraftAccount::createOffline(const QString &username) return account; } +MinecraftAccountPtr MinecraftAccount::createElyby(const QString &username) +{ + MinecraftAccountPtr account = new MinecraftAccount(); + account->data.type = AccountType::Elyby; + account->data.yggdrasilToken.extra["userName"] = username; + account->data.yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); + account->data.minecraftEntitlement.ownsMinecraft = true; + account->data.minecraftEntitlement.canPlayMinecraft = true; + return account; +} + QJsonObject MinecraftAccount::saveToJson() const { @@ -162,6 +174,17 @@ shared_qobject_ptr MinecraftAccount::loginOffline() { return m_currentTask; } +shared_qobject_ptr MinecraftAccount::loginElyby(QString password) { + Q_ASSERT(m_currentTask.get() == nullptr); + + m_currentTask.reset(new ElybyLogin(&data, password)); + connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded())); + connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString))); + connect(m_currentTask.get(), &Task::aborted, this, [this]{ authFailed(tr("Aborted")); }); + emit activityChanged(true); + return m_currentTask; +} + shared_qobject_ptr MinecraftAccount::refresh() { if(m_currentTask) { return m_currentTask; @@ -173,6 +196,9 @@ shared_qobject_ptr MinecraftAccount::refresh() { else if(data.type == AccountType::Offline) { m_currentTask.reset(new OfflineRefresh(&data)); } + else if(data.type == AccountType::Elyby) { + m_currentTask.reset(new ElybyRefresh(&data)); + } else { m_currentTask.reset(new MojangRefresh(&data)); } diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h index 7777f846..923df0f5 100644 --- a/launcher/minecraft/auth/MinecraftAccount.h +++ b/launcher/minecraft/auth/MinecraftAccount.h @@ -95,6 +95,8 @@ public: /* construction */ static MinecraftAccountPtr createOffline(const QString &username); + static MinecraftAccountPtr createElyby(const QString &username); + static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json); static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json); @@ -113,6 +115,8 @@ public: /* manipulation */ shared_qobject_ptr loginOffline(); + shared_qobject_ptr loginElyby(QString password); + shared_qobject_ptr refresh(); shared_qobject_ptr currentTask(); @@ -152,10 +156,18 @@ public: /* queries */ return data.type == AccountType::MSA; } + bool isMojang() const { + return data.type == AccountType::Mojang; + } + bool isOffline() const { return data.type == AccountType::Offline; } + bool isElyby() const { + return data.type == AccountType::Elyby; + } + bool ownsMinecraft() const { return data.minecraftEntitlement.ownsMinecraft; } @@ -180,6 +192,9 @@ public: /* queries */ case AccountType::Offline: { return "offline"; } + case AccountType::Elyby: { + return "elyby"; + } break; default: { return "unknown"; diff --git a/launcher/minecraft/auth/Yggdrasil.cpp b/launcher/minecraft/auth/Yggdrasil.cpp index 29978411..acc026be 100644 --- a/launcher/minecraft/auth/Yggdrasil.cpp +++ b/launcher/minecraft/auth/Yggdrasil.cpp @@ -55,7 +55,7 @@ void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content) { void Yggdrasil::executeTask() { } -void Yggdrasil::refresh() { +void Yggdrasil::refresh(QString baseUrl) { start(); /* * { @@ -84,13 +84,13 @@ void Yggdrasil::refresh() { req.insert("requestUser", false); QJsonDocument doc(req); - QUrl reqUrl("https://authserver.mojang.com/refresh"); + QUrl reqUrl(baseUrl + "refresh"); QByteArray requestData = doc.toJson(); sendRequest(reqUrl, requestData); } -void Yggdrasil::login(QString password) { +void Yggdrasil::login(QString password, QString baseUrl) { start(); /* * { @@ -129,7 +129,7 @@ void Yggdrasil::login(QString password) { QJsonDocument doc(req); - QUrl reqUrl("https://authserver.mojang.com/authenticate"); + QUrl reqUrl(baseUrl + "authenticate"); QNetworkRequest netRequest(reqUrl); QByteArray requestData = doc.toJson(); diff --git a/launcher/minecraft/auth/Yggdrasil.h b/launcher/minecraft/auth/Yggdrasil.h index 4f52a04c..34eb18b2 100644 --- a/launcher/minecraft/auth/Yggdrasil.h +++ b/launcher/minecraft/auth/Yggdrasil.h @@ -40,8 +40,8 @@ public: ); virtual ~Yggdrasil() = default; - void refresh(); - void login(QString password); + void refresh(QString baseUrl); + void login(QString password, QString baseUrl); struct Error { diff --git a/launcher/minecraft/auth/flows/Elyby.cpp b/launcher/minecraft/auth/flows/Elyby.cpp new file mode 100644 index 00000000..72c10472 --- /dev/null +++ b/launcher/minecraft/auth/flows/Elyby.cpp @@ -0,0 +1,24 @@ +#include "Elyby.h" + +#include "minecraft/auth/steps/ElybyStep.h" +#include "minecraft/auth/steps/ElybyProfileStep.h" +#include "minecraft/auth/steps/GetSkinStep.h" + +ElybyRefresh::ElybyRefresh( + AccountData *data, + QObject *parent +) : AuthFlow(data, parent) { + m_steps.append(new ElybyStep(m_data, QString())); + m_steps.append(new ElybyProfileStep(m_data)); + m_steps.append(new GetSkinStep(m_data)); +} + +ElybyLogin::ElybyLogin( + AccountData *data, + QString password, + QObject *parent +): AuthFlow(data, parent), m_password(password) { + m_steps.append(new ElybyStep(m_data, m_password)); + m_steps.append(new ElybyProfileStep(m_data)); + m_steps.append(new GetSkinStep(m_data)); +} diff --git a/launcher/minecraft/auth/flows/Elyby.h b/launcher/minecraft/auth/flows/Elyby.h new file mode 100644 index 00000000..beec3e62 --- /dev/null +++ b/launcher/minecraft/auth/flows/Elyby.h @@ -0,0 +1,26 @@ +#pragma once +#include "AuthFlow.h" + +class ElybyRefresh : public AuthFlow +{ + Q_OBJECT +public: + explicit ElybyRefresh( + AccountData *data, + QObject *parent = 0 + ); +}; + +class ElybyLogin : public AuthFlow +{ + Q_OBJECT +public: + explicit ElybyLogin( + AccountData *data, + QString password, + QObject *parent = 0 + ); + +private: + QString m_password; +}; diff --git a/launcher/minecraft/auth/steps/ElybyProfileStep.cpp b/launcher/minecraft/auth/steps/ElybyProfileStep.cpp new file mode 100644 index 00000000..8cd34ffa --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyProfileStep.cpp @@ -0,0 +1,93 @@ +#include "ElybyProfileStep.h" + +#include + +#include "minecraft/auth/AuthRequest.h" +#include "minecraft/auth/Parsers.h" +#include "net/NetUtils.h" + +ElybyProfileStep::ElybyProfileStep(AccountData* data) : AuthStep(data) { + +} + +ElybyProfileStep::~ElybyProfileStep() noexcept = default; + +QString ElybyProfileStep::describe() { + return tr("Fetching the Minecraft profile."); +} + + +void ElybyProfileStep::perform() { + if (m_data->minecraftProfile.id.isEmpty()) { + emit finished(AccountTaskState::STATE_FAILED_HARD, tr("A UUID is required to get the profile.")); + return; + } + + QUrl url = QUrl("https://authserver.ely.by/session/profile/" + m_data->minecraftProfile.id); + QNetworkRequest req = QNetworkRequest(url); + AuthRequest *request = new AuthRequest(this); + connect(request, &AuthRequest::finished, this, &ElybyProfileStep::onRequestDone); + request->get(req); +} + +void ElybyProfileStep::rehydrate() { + // NOOP, for now. We only save bools and there's nothing to check. +} + +void ElybyProfileStep::onRequestDone( + QNetworkReply::NetworkError error, + QByteArray data, + QList headers +) { + auto requestor = qobject_cast(QObject::sender()); + requestor->deleteLater(); + +#ifndef NDEBUG + qDebug() << data; +#endif + if (error == QNetworkReply::ContentNotFoundError) { + // NOTE: Succeed even if we do not have a profile. This is a valid account state. + m_data->minecraftProfile = MinecraftProfile(); + emit finished( + AccountTaskState::STATE_SUCCEEDED, + tr("Account has no Minecraft profile.") + ); + return; + } + if (error != QNetworkReply::NoError) { + qWarning() << "Error getting profile:"; + qWarning() << " HTTP Status: " << requestor->httpStatus_; + qWarning() << " Internal error no.: " << error; + qWarning() << " Error string: " << requestor->errorString_; + + qWarning() << " Response:"; + qWarning() << QString::fromUtf8(data); + + if (Net::isApplicationError(error)) { + emit finished( + AccountTaskState::STATE_FAILED_SOFT, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) + ); + } + else { + emit finished( + AccountTaskState::STATE_OFFLINE, + tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_) + ); + } + return; + } + if(!Parsers::parseMinecraftProfileMojang(data, m_data->minecraftProfile)) { + m_data->minecraftProfile = MinecraftProfile(); + emit finished( + AccountTaskState::STATE_FAILED_SOFT, + tr("Minecraft Java profile response could not be parsed") + ); + return; + } + + emit finished( + AccountTaskState::STATE_WORKING, + tr("Minecraft Java profile acquisition succeeded.") + ); +} diff --git a/launcher/minecraft/auth/steps/ElybyProfileStep.h b/launcher/minecraft/auth/steps/ElybyProfileStep.h new file mode 100644 index 00000000..765d79e9 --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyProfileStep.h @@ -0,0 +1,22 @@ +#pragma once +#include + +#include "QObjectPtr.h" +#include "minecraft/auth/AuthStep.h" + + +class ElybyProfileStep : public AuthStep { + Q_OBJECT + +public: + explicit ElybyProfileStep(AccountData *data); + virtual ~ElybyProfileStep() noexcept; + + void perform() override; + void rehydrate() override; + + QString describe() override; + +private slots: + void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); +}; diff --git a/launcher/minecraft/auth/steps/ElybyStep.cpp b/launcher/minecraft/auth/steps/ElybyStep.cpp new file mode 100644 index 00000000..e81ebb09 --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyStep.cpp @@ -0,0 +1,52 @@ +#include "ElybyStep.h" + +#include "minecraft/auth/AuthRequest.h" +#include "minecraft/auth/Parsers.h" +#include "minecraft/auth/Yggdrasil.h" + +ElybyStep::ElybyStep(AccountData* data, QString password) : AuthStep(data), m_password(password) { + m_yggdrasil = new Yggdrasil(m_data, this); + + connect(m_yggdrasil, &Task::failed, this, &ElybyStep::onAuthFailed); + connect(m_yggdrasil, &Task::succeeded, this, &ElybyStep::onAuthSucceeded); + connect(m_yggdrasil, &Task::aborted, this, &ElybyStep::onAuthFailed); +} + +ElybyStep::~ElybyStep() noexcept = default; + +QString ElybyStep::describe() { + return tr("Logging in with Ely.by account."); +} + +void ElybyStep::rehydrate() { + // NOOP, for now. +} + +void ElybyStep::perform() { + if(m_password.size()) { + m_yggdrasil->login(m_password, "https://authserver.ely.by/auth/"); + } + else { + m_yggdrasil->refresh("https://authserver.ely.by/auth/"); + } +} + +void ElybyStep::onAuthSucceeded() { + emit finished(AccountTaskState::STATE_WORKING, tr("Logged in with Ely.by")); +} + +void ElybyStep::onAuthFailed() { + // TODO: hook these in again, expand to MSA + // m_error = m_yggdrasil->m_error; + // m_aborted = m_yggdrasil->m_aborted; + + auto state = m_yggdrasil->taskState(); + QString errorMessage = tr("Ely.by user authentication failed."); + + // NOTE: soft error in the first step means 'offline' + if(state == AccountTaskState::STATE_FAILED_SOFT) { + state = AccountTaskState::STATE_OFFLINE; + errorMessage = tr("Ely.by user authentication ended with a network error."); + } + emit finished(state, errorMessage); +} diff --git a/launcher/minecraft/auth/steps/ElybyStep.h b/launcher/minecraft/auth/steps/ElybyStep.h new file mode 100644 index 00000000..5bf8f52c --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyStep.h @@ -0,0 +1,28 @@ +#pragma once +#include + +#include "QObjectPtr.h" +#include "minecraft/auth/AuthStep.h" + +class Yggdrasil; + +class ElybyStep : public AuthStep { + Q_OBJECT + +public: + explicit ElybyStep(AccountData *data, QString password); + virtual ~ElybyStep() noexcept; + + void perform() override; + void rehydrate() override; + + QString describe() override; + +private slots: + void onAuthSucceeded(); + void onAuthFailed(); + +private: + Yggdrasil *m_yggdrasil = nullptr; + QString m_password; +}; diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.cpp b/launcher/minecraft/auth/steps/YggdrasilStep.cpp index e1d33172..d46dce9b 100644 --- a/launcher/minecraft/auth/steps/YggdrasilStep.cpp +++ b/launcher/minecraft/auth/steps/YggdrasilStep.cpp @@ -24,10 +24,10 @@ void YggdrasilStep::rehydrate() { void YggdrasilStep::perform() { if(m_password.size()) { - m_yggdrasil->login(m_password); + m_yggdrasil->login(m_password, "https://authserver.mojang.com/"); } else { - m_yggdrasil->refresh(); + m_yggdrasil->refresh("https://authserver.mojang.com/"); } } diff --git a/launcher/minecraft/launch/InjectAuthlib.cpp b/launcher/minecraft/launch/InjectAuthlib.cpp new file mode 100644 index 00000000..51bc3834 --- /dev/null +++ b/launcher/minecraft/launch/InjectAuthlib.cpp @@ -0,0 +1,173 @@ +/* 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 "InjectAuthlib.h" +#include +#include +#include +#include +#include + +InjectAuthlib::InjectAuthlib(LaunchTask *parent, AuthlibInjectorPtr* injector) : LaunchStep(parent) +{ + m_injector = injector; +} + +void InjectAuthlib::executeTask() +{ + if (m_aborted) + { + emitFailed(tr("Task aborted.")); + return; + } + + auto latestVersionInfo = QString("https://authlib-injector.yushi.moe/artifact/latest.json"); + auto netJob = new NetJob("Injector versions info download", APPLICATION->network()); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("injectors", "version.json"); + if (!m_offlineMode) + { + entry->setStale(true); + auto task = Net::Download::makeCached(QUrl(latestVersionInfo), entry); + netJob->addNetAction(task); + + jobPtr.reset(netJob); + QObject::connect(netJob, &NetJob::succeeded, this, &InjectAuthlib::onVersionDownloadSucceeded); + QObject::connect(netJob, &NetJob::failed, this, &InjectAuthlib::onDownloadFailed); + jobPtr->start(); + } + else + { + onVersionDownloadSucceeded(); + } +} + +void InjectAuthlib::onVersionDownloadSucceeded() +{ + + QByteArray data; + try + { + data = FS::read(QDir("injectors").absoluteFilePath("version.json")); + } + catch (const Exception &e) + { + qCritical() << "Translations Download Failed: index file not readable"; + jobPtr.reset(); + emitFailed("Error while parsing JSON response from InjectorEndpoint"); + return; + } + + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(data, &parse_error); + if (parse_error.error != QJsonParseError::NoError) + { + qCritical() << "Error while parsing JSON response from InjectorEndpoint at " << parse_error.offset << " reason: " << parse_error.errorString(); + qCritical() << data; + jobPtr.reset(); + emitFailed("Error while parsing JSON response from InjectorEndpoint"); + return; + } + + if (!doc.isObject()) + { + qCritical() << "Error while parsing JSON response from InjectorEndpoint root is not object"; + qCritical() << data; + jobPtr.reset(); + emitFailed("Error while parsing JSON response from InjectorEndpoint"); + return; + } + + QString downloadUrl; + try + { + downloadUrl = Json::requireString(doc.object(), "download_url"); + } + catch (const JSONValidationError &e) + { + qCritical() << "Error while parsing JSON response from InjectorEndpoint download url is not string"; + qCritical() << e.cause(); + qCritical() << data; + jobPtr.reset(); + emitFailed("Error while parsing JSON response from InjectorEndpoint"); + return; + } + + QFileInfo fi(downloadUrl); + m_versionName = fi.fileName(); + + qDebug() << "Authlib injector version:" << m_versionName; + if (!m_offlineMode) + { + auto netJob = new NetJob("Injector download", APPLICATION->network()); + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("injectors", m_versionName); + entry->setStale(true); + auto task = Net::Download::makeCached(QUrl(downloadUrl), entry); + netJob->addNetAction(task); + + jobPtr.reset(netJob); + QObject::connect(netJob, &NetJob::succeeded, this, &InjectAuthlib::onDownloadSucceeded); + QObject::connect(netJob, &NetJob::failed, this, &InjectAuthlib::onDownloadFailed); + jobPtr->start(); + } + else + { + onDownloadSucceeded(); + } +} + +void InjectAuthlib::onDownloadSucceeded() +{ + QString injector = QString("%1=%2").arg(QDir("injectors").absoluteFilePath(m_versionName)).arg("ely.by"); + + qDebug() + << "Injecting " << injector; + auto inj = new AuthlibInjector(injector); + m_injector->reset(inj); + + jobPtr.reset(); + emitSucceeded(); +} + +void InjectAuthlib::onDownloadFailed(QString reason) +{ + jobPtr.reset(); + emitFailed(reason); +} + +void InjectAuthlib::proceed() +{ +} + +bool InjectAuthlib::canAbort() const +{ + if (jobPtr) + { + return jobPtr->canAbort(); + } + return true; +} + +bool InjectAuthlib::abort() +{ + m_aborted = true; + if (jobPtr) + { + if (jobPtr->canAbort()) + { + return jobPtr->abort(); + } + } + return true; +} diff --git a/launcher/minecraft/launch/InjectAuthlib.h b/launcher/minecraft/launch/InjectAuthlib.h new file mode 100644 index 00000000..5274f55d --- /dev/null +++ b/launcher/minecraft/launch/InjectAuthlib.h @@ -0,0 +1,75 @@ +/* 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 +#include +#include +#include + +struct AuthlibInjector +{ + QString javaArg; + + AuthlibInjector(const QString arg) + { + javaArg = std::move(arg); + qDebug() << "NEW INJECTOR" << javaArg; + } +}; + +typedef std::shared_ptr AuthlibInjectorPtr; + +// FIXME: stupid. should be defined by the instance type? or even completely abstracted away... +class InjectAuthlib : public LaunchStep +{ + Q_OBJECT +public: + InjectAuthlib(LaunchTask *parent, AuthlibInjectorPtr *injector); + virtual ~InjectAuthlib(){}; + + void executeTask() override; + bool canAbort() const override; + void proceed() override; + + void setAuthServer(QString server) + { + m_authServer = server; + }; + + void setOfflineMode(bool offline) { + m_offlineMode = offline; + } + +public slots: + bool abort() override; + +private slots: + void onVersionDownloadSucceeded(); + void onDownloadSucceeded(); + void onDownloadFailed(QString reason); + +private: + shared_qobject_ptr jobPtr; + bool m_aborted = false; + + bool m_offlineMode; + QString m_versionName; + QString m_authServer; + AuthlibInjectorPtr *m_injector; +}; diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/OSX/scalable/launcher.svg +++ b/launcher/resources/OSX/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/backgrounds/Polly.png b/launcher/resources/backgrounds/Polly.png new file mode 100644 index 00000000..6e4e70a0 Binary files /dev/null and b/launcher/resources/backgrounds/Polly.png differ diff --git a/launcher/resources/backgrounds/PollyChristmas.png b/launcher/resources/backgrounds/PollyChristmas.png new file mode 100644 index 00000000..99dd0ca0 Binary files /dev/null and b/launcher/resources/backgrounds/PollyChristmas.png differ diff --git a/launcher/resources/backgrounds/PollyParty.png b/launcher/resources/backgrounds/PollyParty.png new file mode 100644 index 00000000..e82463d5 Binary files /dev/null and b/launcher/resources/backgrounds/PollyParty.png differ diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc index 52921512..45cc67b1 100644 --- a/launcher/resources/backgrounds/backgrounds.qrc +++ b/launcher/resources/backgrounds/backgrounds.qrc @@ -1,8 +1,8 @@ - catbgrnd2.png - catmas.png - cattiversary.png + Polly.png + PollyChristmas.png + PollyParty.png diff --git a/launcher/resources/backgrounds/licenses b/launcher/resources/backgrounds/licenses new file mode 100644 index 00000000..2b865305 --- /dev/null +++ b/launcher/resources/backgrounds/licenses @@ -0,0 +1,6 @@ +licenses for images here; +Polly.png cc0 +santa-hat.png cc0 +party-hat.png Pixabay License +PollyChristmas.png cc0 +PollyParty.png Pixabay License diff --git a/launcher/resources/backgrounds/party-hat.png b/launcher/resources/backgrounds/party-hat.png new file mode 100644 index 00000000..35dcfcbe Binary files /dev/null and b/launcher/resources/backgrounds/party-hat.png differ diff --git a/launcher/resources/backgrounds/santa-hat.png b/launcher/resources/backgrounds/santa-hat.png new file mode 100644 index 00000000..6026e2cc Binary files /dev/null and b/launcher/resources/backgrounds/santa-hat.png differ diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/flat/scalable/launcher.svg +++ b/launcher/resources/flat/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/iOS/scalable/launcher.svg +++ b/launcher/resources/iOS/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/multimc/scalable/launcher.svg b/launcher/resources/multimc/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/multimc/scalable/launcher.svg +++ b/launcher/resources/multimc/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/pe_blue/scalable/launcher.svg +++ b/launcher/resources/pe_blue/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/pe_colored/scalable/launcher.svg +++ b/launcher/resources/pe_colored/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg index c192d503..64c6d335 100644 --- a/launcher/resources/pe_dark/scalable/launcher.svg +++ b/launcher/resources/pe_dark/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg index a9dfe87a..64c6d335 100644 --- a/launcher/resources/pe_light/scalable/launcher.svg +++ b/launcher/resources/pe_light/scalable/launcher.svg @@ -1,21 +1,99 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + head + + + + + + diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 299401f5..cc6fed64 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -406,7 +406,7 @@ public: actionCAT->setCheckable(true); actionCAT->setIcon(APPLICATION->getThemedIcon("cat")); actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Meow")); - actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3")); + actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a pretty parrot :D")); actionCAT->setPriority(QAction::LowPriority); all_actions.append(&actionCAT); diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 743c34f1..36689e10 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -71,6 +71,17 @@ QString getCreditsHtml() //: %1 is the name of the launcher, determined at build time, e.g. "PolyMC Developers" stream << "

" << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_NAME) << "

\n"; + stream << QString("

fn2006 %1

\n") .arg(getGitHub("fn2006")); + stream << "
\n"; + + //: %1 is the name of the launcher, determined at build time, e.g. "PolyMC Contributors" + stream << "

" << QObject::tr("%1 Contributors", "About Credits").arg(BuildConfig.LAUNCHER_NAME) << "

\n"; + stream << QString("

anoraktrend %1

\n") .arg(getGitHub("anoraktrend")); + stream << QString("

Emma Tebibyte %1

\n") .arg(getWebsite("https://tebibyte.media/")); + stream << "
\n"; + + //: %1 is the name of the launcher, determined at build time, e.g. "PolyMC Developers" + stream << "

" << QObject::tr("%1 Developers", "About Credits").arg("PolyMC") << "

\n"; stream << QString("

LennyMcLennington %1

\n") .arg(getGitHub("LennyMcLennington")); stream << QString("

Sefa Eyeoglu (Scrumplex) %1

\n") .arg(getWebsite("https://scrumplex.net")); stream << QString("

dada513 %1

\n") .arg(getGitHub("dada513")); @@ -81,7 +92,7 @@ QString getCreditsHtml() stream << "
\n"; //: %1 is the name of the launcher, determined at build time, e.g. "PolyMC Contributors" - stream << "

" << QObject::tr("%1 Contributors", "About Credits").arg(BuildConfig.LAUNCHER_NAME) << "

\n"; + stream << "

" << QObject::tr("%1 Contributors", "About Credits").arg("PolyMC") << "

\n"; stream << QString("

DioEgizio %1

\n") .arg(getGitHub("DioEgizio")); stream << QString("

flowln %1

\n") .arg(getGitHub("flowln")); stream << QString("

swirl %1

\n") .arg(getWebsite("https://swurl.xyz/")); @@ -165,7 +176,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia QString urlText("

%1

"); ui->urlLabel->setText(urlText.arg(BuildConfig.LAUNCHER_GIT)); - QString copyText("© 2021-2022 %1"); + QString copyText("%1"); ui->copyLabel->setText(copyText.arg(BuildConfig.LAUNCHER_COPYRIGHT)); connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); diff --git a/launcher/ui/dialogs/ElybyLoginDialog.cpp b/launcher/ui/dialogs/ElybyLoginDialog.cpp new file mode 100644 index 00000000..bc22c4f0 --- /dev/null +++ b/launcher/ui/dialogs/ElybyLoginDialog.cpp @@ -0,0 +1,119 @@ +/* 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 "ElybyLoginDialog.h" +#include "ui_ElybyLoginDialog.h" + +#include "minecraft/auth/AccountTask.h" + +#include + +ElybyLoginDialog::ElybyLoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ElybyLoginDialog) +{ + ui->setupUi(this); + ui->progressBar->setVisible(false); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); +} + +ElybyLoginDialog::~ElybyLoginDialog() +{ + delete ui; +} + +// Stage 1: User interaction +void ElybyLoginDialog::accept() +{ + setUserInputsEnabled(false); + ui->progressBar->setVisible(true); + + // Setup the login task and start it + m_account = MinecraftAccount::createElyby(ui->userTextBox->text()); + m_loginTask = m_account->loginElyby(ui->passTextBox->text()); + connect(m_loginTask.get(), &Task::failed, this, &ElybyLoginDialog::onTaskFailed); + connect(m_loginTask.get(), &Task::succeeded, this, &ElybyLoginDialog::onTaskSucceeded); + connect(m_loginTask.get(), &Task::status, this, &ElybyLoginDialog::onTaskStatus); + connect(m_loginTask.get(), &Task::progress, this, &ElybyLoginDialog::onTaskProgress); + m_loginTask->start(); +} + +void ElybyLoginDialog::setUserInputsEnabled(bool enable) +{ + ui->userTextBox->setEnabled(enable); + ui->passTextBox->setEnabled(enable); + ui->buttonBox->setEnabled(enable); +} + +// Enable the OK button only when both textboxes contain something. +void ElybyLoginDialog::on_userTextBox_textEdited(const QString &newText) +{ + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty()); +} +void ElybyLoginDialog::on_passTextBox_textEdited(const QString &newText) +{ + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty()); +} + +void ElybyLoginDialog::onTaskFailed(const QString &reason) +{ + // Set message + auto lines = reason.split('\n'); + QString processed; + for(auto line: lines) { + if(line.size()) { + processed += "" + line + "
"; + } + else { + processed += "
"; + } + } + ui->label->setText(processed); + + // Re-enable user-interaction + setUserInputsEnabled(true); + ui->progressBar->setVisible(false); +} + +void ElybyLoginDialog::onTaskSucceeded() +{ + QDialog::accept(); +} + +void ElybyLoginDialog::onTaskStatus(const QString &status) +{ + ui->label->setText(status); +} + +void ElybyLoginDialog::onTaskProgress(qint64 current, qint64 total) +{ + ui->progressBar->setMaximum(total); + ui->progressBar->setValue(current); +} + +// Public interface +MinecraftAccountPtr ElybyLoginDialog::newAccount(QWidget *parent, QString msg) +{ + ElybyLoginDialog dlg(parent); + dlg.ui->label->setText(msg); + if (dlg.exec() == QDialog::Accepted) + { + return dlg.m_account; + } + return nullptr; +} diff --git a/launcher/ui/dialogs/ElybyLoginDialog.h b/launcher/ui/dialogs/ElybyLoginDialog.h new file mode 100644 index 00000000..4b81c0b8 --- /dev/null +++ b/launcher/ui/dialogs/ElybyLoginDialog.h @@ -0,0 +1,59 @@ +/* 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 "minecraft/auth/MinecraftAccount.h" +#include "tasks/Task.h" + +namespace Ui +{ +class ElybyLoginDialog; +} + +class ElybyLoginDialog : public QDialog +{ + Q_OBJECT + +public: + ~ElybyLoginDialog(); + + static MinecraftAccountPtr newAccount(QWidget *parent, QString message); + +private: + explicit ElybyLoginDialog(QWidget *parent = 0); + + void setUserInputsEnabled(bool enable); + +protected +slots: + void accept(); + + void onTaskFailed(const QString &reason); + void onTaskSucceeded(); + void onTaskStatus(const QString &status); + void onTaskProgress(qint64 current, qint64 total); + + void on_userTextBox_textEdited(const QString &newText); + void on_passTextBox_textEdited(const QString &newText); + +private: + Ui::ElybyLoginDialog *ui; + MinecraftAccountPtr m_account; + Task::Ptr m_loginTask; +}; diff --git a/launcher/ui/dialogs/ElybyLoginDialog.ui b/launcher/ui/dialogs/ElybyLoginDialog.ui new file mode 100644 index 00000000..4b03ebf9 --- /dev/null +++ b/launcher/ui/dialogs/ElybyLoginDialog.ui @@ -0,0 +1,77 @@ + + + ElybyLoginDialog + + + + 0 + 0 + 421 + 198 + + + + + 0 + 0 + + + + Add Account + + + + + + Message label placeholder. + + + Qt::RichText + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Email + + + + + + + QLineEdit::Password + + + Password + + + + + + + 24 + + + false + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index a4f4dfb9..18f20647 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -48,6 +48,7 @@ #include "ui/dialogs/OfflineLoginDialog.h" #include "ui/dialogs/LoginDialog.h" #include "ui/dialogs/MSALoginDialog.h" +#include "ui/dialogs/ElybyLoginDialog.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/SkinUploadDialog.h" @@ -188,19 +189,6 @@ void AccountListPage::on_actionAddMicrosoft_triggered() void AccountListPage::on_actionAddOffline_triggered() { - if (!m_accounts->anyAccountIsValid()) { - QMessageBox::warning( - this, - tr("Error"), - tr( - "You must add a Microsoft or Mojang account that owns Minecraft before you can add an offline account." - "

" - "If you have lost your account you can contact Microsoft for support." - ) - ); - return; - } - MinecraftAccountPtr account = OfflineLoginDialog::newAccount( this, tr("Please enter your desired username to add your offline account.") @@ -215,6 +203,22 @@ void AccountListPage::on_actionAddOffline_triggered() } } +void AccountListPage::on_actionAddElyby_triggered() +{ + MinecraftAccountPtr account = ElybyLoginDialog::newAccount( + this, + tr("Please enter your Ely.by account email and password to add your account.") + ); + + if (account) + { + m_accounts->addAccount(account); + if (m_accounts->count() == 1) { + m_accounts->setDefaultAccount(account); + } + } +} + void AccountListPage::on_actionRemove_triggered() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); @@ -258,17 +262,20 @@ void AccountListPage::updateButtonStates() bool hasSelection = !selection.empty(); bool accountIsReady = false; bool accountIsOnline = false; + bool accountIsElyby = false; if (hasSelection) { QModelIndex selected = selection.first(); MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value(); accountIsReady = !account->isActive(); accountIsOnline = !account->isOffline(); + accountIsElyby = account->isElyby(); + } ui->actionRemove->setEnabled(accountIsReady); ui->actionSetDefault->setEnabled(accountIsReady); - ui->actionUploadSkin->setEnabled(accountIsReady && accountIsOnline); - ui->actionDeleteSkin->setEnabled(accountIsReady && accountIsOnline); + ui->actionUploadSkin->setEnabled(accountIsReady && accountIsOnline && !accountIsElyby); + ui->actionDeleteSkin->setEnabled(accountIsReady && accountIsOnline && !accountIsElyby); ui->actionRefresh->setEnabled(accountIsReady && accountIsOnline); if(m_accounts->defaultAccount().get() == nullptr) { diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h index 9395e92b..1812c5e5 100644 --- a/launcher/ui/pages/global/AccountListPage.h +++ b/launcher/ui/pages/global/AccountListPage.h @@ -85,6 +85,7 @@ public slots: void on_actionAddMojang_triggered(); void on_actionAddMicrosoft_triggered(); void on_actionAddOffline_triggered(); + void on_actionAddElyby_triggered(); void on_actionRemove_triggered(); void on_actionRefresh_triggered(); void on_actionSetDefault_triggered(); diff --git a/launcher/ui/pages/global/AccountListPage.ui b/launcher/ui/pages/global/AccountListPage.ui index 469955b5..e5d76ec4 100644 --- a/launcher/ui/pages/global/AccountListPage.ui +++ b/launcher/ui/pages/global/AccountListPage.ui @@ -55,6 +55,7 @@ + @@ -109,6 +110,11 @@ Add &Offline + + + Add &Ely.by + + &Refresh diff --git a/nix/NIX.md b/nix/NIX.md index 047dd82f..96af194b 100644 --- a/nix/NIX.md +++ b/nix/NIX.md @@ -5,22 +5,22 @@ To import with flakes use ```nix { inputs = { - polymc.url = "github:PolyMC/PolyMC"; + pollymc.url = "github:fn2006/PollyMC"; }; ... - nixpkgs.overlays = [ inputs.polymc.overlay ]; ## Within configuration.nix - environment.systemPackages = with pkgs; [ polymc ]; ## + nixpkgs.overlays = [ inputs.pollymc.overlay ]; ## Within configuration.nix + environment.systemPackages = with pkgs; [ pollymc ]; ## } ``` To import without flakes use channels: ```sh -nix-channel --add https://github.com/PolyMC/PolyMC/archive/master.tar.gz polymc -nix-channel --update polymc -nix-env -iA polymc +nix-channel --add https://github.com/fn2006/PollyMC/archive/master.tar.gz pollymc +nix-channel --update pollymc +nix-env -iA pollymc ``` or alternatively you can use @@ -28,9 +28,9 @@ or alternatively you can use ```nix { nixpkgs.overlays = [ - (import (builtins.fetchTarball "https://github.com/PolyMC/PolyMC/archive/develop.tar.gz")).overlay + (import (builtins.fetchTarball "https://github.com/fn2006/PollyMC/archive/develop.tar.gz")).overlay ]; - environment.systemPackages = with pkgs; [ polymc ]; + environment.systemPackages = with pkgs; [ pollymc ]; } ``` diff --git a/nix/default.nix b/nix/default.nix index 42ddda18..2cee82f3 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -43,7 +43,7 @@ let in stdenv.mkDerivation rec { - pname = "polymc"; + pname = "pollymc"; inherit version; src = lib.cleanSource self; @@ -70,7 +70,7 @@ stdenv.mkDerivation rec { # we have to check if the system is NixOS before adding stdenv.cc.cc.lib (#923) postInstall = '' # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128 - wrapQtApp $out/bin/polymc \ + wrapQtApp $out/bin/pollymc \ --run '[ -f /etc/NIXOS ] && export LD_LIBRARY_PATH="${stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH"' \ --prefix LD_LIBRARY_PATH : ${gameLibraryPath} \ --prefix POLYMC_JAVA_PATHS : ${javaPaths} \ @@ -78,9 +78,9 @@ stdenv.mkDerivation rec { ''; meta = with lib; { - homepage = "https://polymc.org/"; - downloadPage = "https://polymc.org/download/"; - changelog = "https://github.com/PolyMC/PolyMC/releases"; + homepage = "https://github.com/fn2006/PollyMC"; + downloadPage = "https://github.com/fn2006/PollyMC/releases"; + changelog = "https://github.com/fn2006/PollyMC/releases"; description = "A free, open source launcher for Minecraft"; longDescription = '' Allows you to have multiple, separate instances of Minecraft (each with diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index ac8ea6ce..9ce3623f 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -8,44 +8,44 @@ if(UNIX) endif() endif() -set(Launcher_CommonName "PolyMC") +set(Launcher_CommonName "PollyMC") -set(Launcher_Copyright "PolyMC Contributors\\n© 2012-2021 MultiMC Contributors") +set(Launcher_Copyright "© 2022 PollyMC Contributors\\n© 2021-2022 PolyMC Contributors\\n© 2012-2021 MultiMC Contributors") set(Launcher_Copyright "${Launcher_Copyright}" PARENT_SCOPE) -set(Launcher_Domain "polymc.org" PARENT_SCOPE) +set(Launcher_Domain "" PARENT_SCOPE) set(Launcher_Name "${Launcher_CommonName}" PARENT_SCOPE) set(Launcher_DisplayName "${Launcher_CommonName}" PARENT_SCOPE) -set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_SCOPE) -set(Launcher_ConfigFile "polymc.cfg" PARENT_SCOPE) -set(Launcher_Git "https://github.com/PolyMC/PolyMC" PARENT_SCOPE) -set(Launcher_DesktopFileName "org.polymc.PolyMC.desktop" PARENT_SCOPE) +set(Launcher_UserAgent "PolyMC/${Launcher_RELEASE_VERSION_NAME}" PARENT_SCOPE) +set(Launcher_ConfigFile "pollymc.cfg" PARENT_SCOPE) +set(Launcher_Git "https://github.com/fn2006/PollyMC" PARENT_SCOPE) +set(Launcher_DesktopFileName "org.fn2006.PollyMC.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_SVG "program_info/org.polymc.PolyMC.svg" PARENT_SCOPE) +set(Launcher_Desktop "program_info/org.fn2006.PollyMC.desktop" PARENT_SCOPE) +set(Launcher_MetaInfo "program_info/org.fn2006.PollyMC.metainfo.xml" PARENT_SCOPE) +set(Launcher_SVG "program_info/org.fn2006.PollyMC.svg" PARENT_SCOPE) set(Launcher_Branding_ICNS "program_info/polymc.icns" PARENT_SCOPE) -set(Launcher_Branding_ICO "program_info/polymc.ico") +set(Launcher_Branding_ICO "program_info/pollymc.ico") set(Launcher_Branding_ICO "${Launcher_Branding_ICO}" PARENT_SCOPE) -set(Launcher_Branding_WindowsRC "program_info/polymc.rc" PARENT_SCOPE) +set(Launcher_Branding_WindowsRC "program_info/pollymc.rc" PARENT_SCOPE) set(Launcher_Branding_LogoQRC "program_info/polymc.qrc" PARENT_SCOPE) set(Launcher_Portable_File "program_info/portable.txt" PARENT_SCOPE) -configure_file(org.polymc.PolyMC.desktop.in org.polymc.PolyMC.desktop) -configure_file(org.polymc.PolyMC.metainfo.xml.in org.polymc.PolyMC.metainfo.xml) -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(org.fn2006.PollyMC.desktop.in org.fn2006.PollyMC.desktop) +configure_file(org.fn2006.PollyMC.metainfo.xml.in org.fn2006.PollyMC.metainfo.xml) +configure_file(pollymc.rc.in pollymc.rc @ONLY) +configure_file(pollymc.manifest.in pollymc.manifest @ONLY) +configure_file(pollymc.ico pollymc.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") + set(in_scd "${CMAKE_CURRENT_SOURCE_DIR}/pollymc.6.scd") + set(out_man "${CMAKE_CURRENT_BINARY_DIR}/pollymc.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) + set(Launcher_ManPage "program_info/pollymc.6" PARENT_SCOPE) endif() diff --git a/program_info/genicons.sh b/program_info/genicons.sh index 313bdb53..60a437d8 100755 --- a/program_info/genicons.sh +++ b/program_info/genicons.sh @@ -2,38 +2,38 @@ # ICO -inkscape -w 16 -h 16 -o polymc_16.png org.polymc.PolyMC.svg -inkscape -w 24 -h 24 -o polymc_24.png org.polymc.PolyMC.svg -inkscape -w 32 -h 32 -o polymc_32.png org.polymc.PolyMC.svg -inkscape -w 48 -h 48 -o polymc_48.png org.polymc.PolyMC.svg -inkscape -w 64 -h 64 -o polymc_64.png org.polymc.PolyMC.svg -inkscape -w 128 -h 128 -o polymc_128.png org.polymc.PolyMC.svg +inkscape -w 16 -h 16 -o pollymc_16.png org.fn2006.PollyMC.svg +inkscape -w 24 -h 24 -o pollymc_24.png org.fn2006.PollyMC.svg +inkscape -w 32 -h 32 -o pollymc_32.png org.fn2006.PollyMC.svg +inkscape -w 48 -h 48 -o pollymc_48.png org.fn2006.PollyMC.svg +inkscape -w 64 -h 64 -o pollymc_64.png org.fn2006.PollyMC.svg +inkscape -w 128 -h 128 -o pollymc_128.png org.fn2006.PollyMC.svg -convert polymc_128.png polymc_64.png polymc_48.png polymc_32.png polymc_24.png polymc_16.png polymc.ico +convert pollymc_128.png pollymc_64.png pollymc_48.png pollymc_32.png pollymc_24.png pollymc_16.png pollymc.ico -rm -f polymc_*.png +rm -f pollymc_*.png -inkscape -w 1024 -h 1024 -o polymc_1024.png org.polymc.PolyMC.bigsur.svg +inkscape -w 1024 -h 1024 -o pollymc_1024.png org.fn2006.PollyMC.bigsur.svg -mkdir polymc.iconset +mkdir pollymc.iconset -sips -z 16 16 polymc_1024.png --out polymc.iconset/icon_16x16.png -sips -z 32 32 polymc_1024.png --out polymc.iconset/icon_16x16@2x.png -sips -z 32 32 polymc_1024.png --out polymc.iconset/icon_32x32.png -sips -z 64 64 polymc_1024.png --out polymc.iconset/icon_32x32@2x.png -sips -z 128 128 polymc_1024.png --out polymc.iconset/icon_128x128.png -sips -z 256 256 polymc_1024.png --out polymc.iconset/icon_128x128@2x.png -sips -z 256 256 polymc_1024.png --out polymc.iconset/icon_256x256.png -sips -z 512 512 polymc_1024.png --out polymc.iconset/icon_256x256@2x.png -sips -z 512 512 polymc_1024.png --out polymc.iconset/icon_512x512.png -cp polymc_1024.png polymc.iconset/icon_512x512@2x.png +magick pollymc_1024.png -resize 16x16 pollymc.iconset/icon_16x16.png +magick pollymc_1024.png -resize 32x32 pollymc.iconset/icon_16x16@2x.png +magick pollymc_1024.png -resize 32x32 pollymc.iconset/icon_32x32.png +magick pollymc_1024.png -resize 64x64 pollymc.iconset/icon_32x32@2x.png +magick pollymc_1024.png -resize 128x128 pollymc.iconset/icon_128x128.png +magick pollymc_1024.png -resize 256x256 pollymc.iconset/icon_128x128@2x.png +magick pollymc_1024.png -resize 256x256 pollymc.iconset/icon_256x256.png +magick pollymc_1024.png -resize 512x512 pollymc.iconset/icon_256x256@2x.png +magick pollymc_1024.png -resize 512x512 pollymc.iconset/icon_512x512.png +cp pollymc_1024.png pollymc.iconset/icon_512x512@2x.png -iconutil -c icns polymc.iconset +icnsify -i pollymc_1024.png -o pollymc.icns -rm -f polymc_*.png -rm -rf polymc.iconset +rm -f pollymc_*.png +rm -rf pollymc.iconset for dir in ../launcher/resources/*/scalable do - cp -v org.polymc.PolyMC.svg $dir/launcher.svg + cp -v org.fn2006.PollyMC.svg $dir/launcher.svg done diff --git a/program_info/org.fn2006.PollyMC Source.svg b/program_info/org.fn2006.PollyMC Source.svg new file mode 100644 index 00000000..d09ac6ea --- /dev/null +++ b/program_info/org.fn2006.PollyMC Source.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + head2 + + + head1 + + + head + + + + + + + + + + + diff --git a/program_info/org.fn2006.PollyMC.bigsur.svg b/program_info/org.fn2006.PollyMC.bigsur.svg new file mode 100644 index 00000000..e3bd4615 --- /dev/null +++ b/program_info/org.fn2006.PollyMC.bigsur.svg @@ -0,0 +1,207 @@ + +head diff --git a/program_info/org.fn2006.PollyMC.desktop.in b/program_info/org.fn2006.PollyMC.desktop.in new file mode 100755 index 00000000..12a3a6d0 --- /dev/null +++ b/program_info/org.fn2006.PollyMC.desktop.in @@ -0,0 +1,13 @@ +#!/usr/bin/env xdg-open +[Desktop Entry] +Version=1.0 +Name=PollyMC +Comment=A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once. +Type=Application +Terminal=false +Exec=@Launcher_APP_BINARY_NAME@ +StartupNotify=true +Icon=org.fn2006.PollyMC +Categories=Game; +Keywords=game;minecraft;launcher;mc; +StartupWMClass=PollyMC diff --git a/program_info/org.fn2006.PollyMC.metainfo.xml.in b/program_info/org.fn2006.PollyMC.metainfo.xml.in new file mode 100644 index 00000000..2cabc459 --- /dev/null +++ b/program_info/org.fn2006.PollyMC.metainfo.xml.in @@ -0,0 +1,35 @@ + + + org.fn2006.PollyMC + + org.fn2006.PollyMC + + org.fn2006.PollyMC.desktop + PollyMC + fn2006C + A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once + CC0-1.0 + GPL-3.0-only + https://github.com/fn2006/PollyMC/ + https://polymc.org/wiki/ + +

PollyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.

+

Features:

+
    +
  • Easily install game modifications, such as Fabric, Forge and Quilt
  • +
  • Control your java settings
  • +
  • Manage worlds and resource packs from the launcher
  • +
  • See logs and other details easily
  • +
  • Kill Minecraft in case of a crash/freeze
  • +
  • Isolate minecraft instances to keep everything clean
  • +
  • Install and update mods directly from the launcher
  • +
+
+ + + + + moderate + intense + +
diff --git a/program_info/org.fn2006.PollyMC.svg b/program_info/org.fn2006.PollyMC.svg new file mode 100644 index 00000000..64f8da74 --- /dev/null +++ b/program_info/org.fn2006.PollyMC.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + diff --git a/program_info/pollymc-header-black.svg b/program_info/pollymc-header-black.svg new file mode 100644 index 00000000..9289d138 --- /dev/null +++ b/program_info/pollymc-header-black.svg @@ -0,0 +1,143 @@ + + + + diff --git a/program_info/pollymc-header.Source.svg b/program_info/pollymc-header.Source.svg new file mode 100644 index 00000000..f05a73b9 --- /dev/null +++ b/program_info/pollymc-header.Source.svg @@ -0,0 +1,145 @@ + + + +PollyMC diff --git a/program_info/pollymc-header.svg b/program_info/pollymc-header.svg new file mode 100644 index 00000000..ad67d9f9 --- /dev/null +++ b/program_info/pollymc-header.svg @@ -0,0 +1,143 @@ + + + + diff --git a/program_info/pollymc.6.scd b/program_info/pollymc.6.scd new file mode 100644 index 00000000..3a34d544 --- /dev/null +++ b/program_info/pollymc.6.scd @@ -0,0 +1,61 @@ +pollymc(6) + + +# NAME + +pollymc - a launcher and instance manager for Minecraft. + + +# SYNOPSIS + +*pollymc* [OPTIONS...] + + +# DESCRIPTION + +PollyMC 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 PollyMC. + +# OPTIONS + +*-d, --dir*=DIRECTORY + Use DIRECTORY as the PollyMC root. + +*-l, --launch*=INSTANCE_ID + Launch the instance specified by INSTANCE_ID. + +*--alive* + Write a small 'live.check' file after PollyMC 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/fn2006/PollyMC/issues + +# RESOURCES + +GitHub: https://github.com/fn2006/PollyMC + +# AUTHORS + +PollyMC Contributors + +PolyMC Contributors diff --git a/program_info/pollymc.icns b/program_info/pollymc.icns new file mode 100644 index 00000000..d9a1b86b Binary files /dev/null and b/program_info/pollymc.icns differ diff --git a/program_info/pollymc.ico b/program_info/pollymc.ico new file mode 100644 index 00000000..8664059e Binary files /dev/null and b/program_info/pollymc.ico differ diff --git a/program_info/pollymc.manifest.in b/program_info/pollymc.manifest.in new file mode 100644 index 00000000..3756c706 --- /dev/null +++ b/program_info/pollymc.manifest.in @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + Custom Minecraft launcher for managing multiple installs. + + + + + + + + + + + + + diff --git a/program_info/pollymc.qrc b/program_info/pollymc.qrc new file mode 100644 index 00000000..44558322 --- /dev/null +++ b/program_info/pollymc.qrc @@ -0,0 +1,6 @@ + + + + org.fn2006.PollyMC.svg + + diff --git a/program_info/pollymc.rc.in b/program_info/pollymc.rc.in new file mode 100644 index 00000000..571691ce --- /dev/null +++ b/program_info/pollymc.rc.in @@ -0,0 +1,29 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +IDI_ICON1 ICON DISCARDABLE "pollymc.ico" +1 RT_MANIFEST "pollymc.manifest" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION @Launcher_VERSION_NAME4_COMMA@ +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "MultiMC & PolyMC & PollyMC Contributors" + VALUE "FileDescription", "PollyMC" + VALUE "FileVersion", "@Launcher_VERSION_NAME4@" + VALUE "ProductName", "PollyMC" + VALUE "ProductVersion", "@Launcher_VERSION_NAME4@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04b0 // Unicode + END +END diff --git a/program_info/polymc.qrc b/program_info/polymc.qrc index 9ea695de..44558322 100644 --- a/program_info/polymc.qrc +++ b/program_info/polymc.qrc @@ -1,6 +1,6 @@ - org.polymc.PolyMC.svg + org.fn2006.PollyMC.svg