Merge remote-tracking branch 'upstream/develop' into unused-code

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2025-09-19 11:06:34 +01:00
commit d384970694
No known key found for this signature in database
GPG key ID: 5E39D70B4C93C38E
314 changed files with 4368 additions and 4638 deletions

View file

@ -31,6 +31,28 @@ runs:
using: composite
steps:
- name: Setup build variables
shell: bash
run: |
# Fixup architecture naming for AppImages
dpkg_arch="$(dpkg-architecture -q DEB_HOST_ARCH_CPU)"
case "$dpkg_arch" in
"amd64")
APPIMAGE_ARCH="x86_64"
;;
"arm64")
APPIMAGE_ARCH="aarch64"
;;
*)
echo "# 🚨 The Debian architecture \"$deb_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
exit 1
;;
esac
echo "APPIMAGE_ARCH=$APPIMAGE_ARCH" >> "$GITHUB_ENV"
# Used for the file paths of libraries
echo "DEB_HOST_MULTIARCH=$(dpkg-architecture -q DEB_HOST_MULTIARCH)" >> "$GITHUB_ENV"
- name: Package AppImage
shell: bash
env:
@ -45,26 +67,26 @@ runs:
mv ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.metainfo.xml ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/metainfo/org.prismlauncher.PrismLauncher.appdata.xml
export "NO_APPSTREAM=1" # we have to skip appstream checking because appstream on ubuntu 20.04 is outdated
export OUTPUT="PrismLauncher-Linux-x86_64.AppImage"
export OUTPUT="PrismLauncher-Linux-$APPIMAGE_ARCH.AppImage"
chmod +x linuxdeploy-*.AppImage
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
cp -r ${{ runner.workspace }}/Qt/${{ inputs.qt-version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
cp -r ${{ runner.workspace }}/Qt/${{ inputs.qt-version }}/gcc_*64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libssl.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/"$DEB_HOST_MULTIARCH"/libcrypto.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/"$DEB_HOST_MULTIARCH"/libssl.so.* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
cp /usr/lib/"$DEB_HOST_MULTIARCH"/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
export LD_LIBRARY_PATH
chmod +x AppImageUpdate-x86_64.AppImage
cp AppImageUpdate-x86_64.AppImage ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin
chmod +x AppImageUpdate-"$APPIMAGE_ARCH".AppImage
cp AppImageUpdate-"$APPIMAGE_ARCH".AppImage ${{ env.INSTALL_APPIMAGE_DIR }}/usr/bin
export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|PrismLauncher-Linux-x86_64.AppImage.zsync"
export UPDATE_INFORMATION="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|PrismLauncher-Linux-$APPIMAGE_ARCH.AppImage.zsync"
if [ '${{ inputs.gpg-private-key-id }}' != '' ]; then
export SIGN=1
@ -76,9 +98,9 @@ runs:
echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY
fi
./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.prismlauncher.PrismLauncher.svg
./linuxdeploy-"$APPIMAGE_ARCH".AppImage --appdir ${{ env.INSTALL_APPIMAGE_DIR }} --output appimage --plugin qt -i ${{ env.INSTALL_APPIMAGE_DIR }}/usr/share/icons/hicolor/scalable/apps/org.prismlauncher.PrismLauncher.svg
mv "PrismLauncher-Linux-x86_64.AppImage" "PrismLauncher-Linux-${{ env.VERSION }}-${{ inputs.build-type }}-x86_64.AppImage"
mv "PrismLauncher-Linux-$APPIMAGE_ARCH.AppImage" "PrismLauncher-Linux-${{ env.VERSION }}-${{ inputs.build-type }}-$APPIMAGE_ARCH.AppImage"
- name: Package portable tarball
shell: bash
@ -89,17 +111,8 @@ runs:
INSTALL_PORTABLE_DIR: install-portable
run: |
cmake --preset "$CMAKE_PRESET" -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_PORTABLE_DIR }} -DINSTALL_BUNDLE=full
cmake --install ${{ env.BUILD_DIR }}
cmake --install ${{ env.BUILD_DIR }} --component portable
mkdir ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /lib/x86_64-linux-gnu/libbz2.so.1.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libssl.so.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
cp /usr/lib/x86_64-linux-gnu/libffi.so.*.* ${{ env.INSTALL_PORTABLE_DIR }}/lib
mv ${{ env.INSTALL_PORTABLE_DIR }}/bin/*.so* ${{ env.INSTALL_PORTABLE_DIR }}/lib
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
cd ${{ env.INSTALL_PORTABLE_DIR }}
@ -114,11 +127,11 @@ runs:
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: PrismLauncher-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}-x86_64.AppImage
path: PrismLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-x86_64.AppImage
name: PrismLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
path: PrismLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage
- name: Upload AppImage Zsync
uses: actions/upload-artifact@v4
with:
name: PrismLauncher-${{ inputs.artifact-name }}-${{ inputs.version }}-${{ inputs.build-type }}-x86_64.AppImage.zsync
path: PrismLauncher-Linux-x86_64.AppImage.zsync
name: PrismLauncher-${{ runner.os }}-${{ inputs.version }}-${{ inputs.build-type }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync
path: PrismLauncher-${{ runner.os }}-${{ env.APPIMAGE_ARCH }}.AppImage.zsync

View file

@ -6,6 +6,9 @@ inputs:
description: Type for the build
required: true
default: Debug
artifact-name:
description: Name of the uploaded artifact
required: true
msystem:
description: MSYS2 subsystem to use
required: false
@ -18,7 +21,7 @@ inputs:
qt-version:
description: Version of Qt to use
required: true
default: 6.8.1
default: 6.9.1
outputs:
build-type:
@ -39,6 +42,8 @@ runs:
- name: Setup macOS dependencies
if: ${{ runner.os == 'macOS' }}
uses: ./.github/actions/setup-dependencies/macos
with:
build-type: ${{ inputs.build-type }}
- name: Setup Windows dependencies
if: ${{ runner.os == 'Windows' }}
@ -51,18 +56,18 @@ runs:
# TODO(@getchoo): Get this working on MSYS2!
- name: Setup ccache
if: ${{ (runner.os != 'Windows' || inputs.msystem == '') && inputs.build-type == 'Debug' }}
uses: hendrikmuhs/ccache-action@v1.2.18
uses: hendrikmuhs/ccache-action@v1.2.19
with:
variant: ${{ runner.os == 'Windows' && 'sccache' || 'ccache' }}
variant: sccache
create-symlink: ${{ runner.os != 'Windows' }}
key: ${{ runner.os }}-qt${{ inputs.qt_ver }}-${{ inputs.architecture }}
key: ${{ runner.os }}-${{ runner.arch }}-${{ inputs.artifact-name }}-sccache
- name: Use ccache on debug builds
if: ${{ inputs.build-type == 'Debug' }}
shell: bash
env:
# Only use sccache on MSVC
CCACHE_VARIANT: ${{ (runner.os == 'Windows' && inputs.msystem == '') && 'sccache' || 'ccache' }}
# Only use ccache on MSYS2
CCACHE_VARIANT: ${{ (runner.os == 'Windows' && inputs.msystem != '') && 'ccache' || 'sccache' }}
run: |
echo "CMAKE_C_COMPILER_LAUNCHER=$CCACHE_VARIANT" >> "$GITHUB_ENV"
echo "CMAKE_CXX_COMPILER_LAUNCHER=$CCACHE_VARIANT" >> "$GITHUB_ENV"

View file

@ -8,15 +8,33 @@ runs:
shell: bash
run: |
sudo apt-get -y update
sudo apt-get -y install ninja-build extra-cmake-modules scdoc appstream libxcb-cursor-dev
sudo apt-get -y install \
dpkg-dev \
ninja-build extra-cmake-modules scdoc \
appstream libxcb-cursor-dev
- name: Setup AppImage tooling
shell: bash
run: |
declare -A appimage_deps
appimage_deps["https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-x86_64.AppImage"]="4648f278ab3ef31f819e67c30d50f462640e5365a77637d7e6f2ad9fd0b4522a linuxdeploy-x86_64.AppImage"
appimage_deps["https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/linuxdeploy-plugin-qt-x86_64.AppImage"]="15106be885c1c48a021198e7e1e9a48ce9d02a86dd0a1848f00bdbf3c1c92724 linuxdeploy-plugin-qt-x86_64.AppImage"
appimage_deps["https://github.com/AppImageCommunity/AppImageUpdate/releases/download/2.0.0-alpha-1-20241225/AppImageUpdate-x86_64.AppImage"]="f1747cf60058e99f1bb9099ee9787d16c10241313b7acec81810ea1b1e568c11 AppImageUpdate-x86_64.AppImage"
deb_arch="$(dpkg-architecture -q DEB_HOST_ARCH)"
case "$deb_arch" in
"amd64")
appimage_deps["https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-x86_64.AppImage"]="4648f278ab3ef31f819e67c30d50f462640e5365a77637d7e6f2ad9fd0b4522a linuxdeploy-x86_64.AppImage"
appimage_deps["https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/linuxdeploy-plugin-qt-x86_64.AppImage"]="15106be885c1c48a021198e7e1e9a48ce9d02a86dd0a1848f00bdbf3c1c92724 linuxdeploy-plugin-qt-x86_64.AppImage"
appimage_deps["https://github.com/AppImageCommunity/AppImageUpdate/releases/download/2.0.0-alpha-1-20241225/AppImageUpdate-x86_64.AppImage"]="f1747cf60058e99f1bb9099ee9787d16c10241313b7acec81810ea1b1e568c11 AppImageUpdate-x86_64.AppImage"
;;
"arm64")
appimage_deps["https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-aarch64.AppImage"]="06706ac8189797dccd36bd384105892cb5e6e71f784f4df526cc958adc223cd6 linuxdeploy-aarch64.AppImage"
appimage_deps["https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/linuxdeploy-plugin-qt-aarch64.AppImage"]="bf1c24aff6d749b5cf423afad6f15abd4440f81dec1aab95706b25f6667cdcf1 linuxdeploy-plugin-qt-aarch64.AppImage"
appimage_deps["https://github.com/AppImageCommunity/AppImageUpdate/releases/download/2.0.0-alpha-1-20241225/AppImageUpdate-aarch64.AppImage"]="cf27f810dfe5eda41f130769e4a4b562b9d93665371c15ebeffb84ee06a41550 AppImageUpdate-aarch64.AppImage"
;;
*)
echo "# 🚨 The Debian architecture \"$deb_arch\" is not recognized!" >> "$GITHUB_STEP_SUMMARY"
exit 1
;;
esac
for url in "${!appimage_deps[@]}"; do
curl -LO "$url"

View file

@ -1,5 +1,11 @@
name: Setup macOS dependencies
inputs:
build-type:
description: Type for the build
required: true
default: Debug
runs:
using: composite
@ -14,3 +20,29 @@ runs:
shell: bash
run: |
echo "JAVA_HOME=$(/usr/libexec/java_home -v 17)" >> "$GITHUB_ENV"
- name: Setup vcpkg cache
if: ${{ inputs.build-type == 'Debug' }}
shell: bash
env:
USERNAME: ${{ github.repository_owner }}
GITHUB_TOKEN: ${{ github.token }}
FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
run: |
mono `vcpkg fetch nuget | tail -n 1` \
sources add \
-Source "$FEED_URL" \
-StorePasswordInClearText \
-Name GitHubPackages \
-UserName "$USERNAME" \
-Password "$GITHUB_TOKEN"
mono `vcpkg fetch nuget | tail -n 1` \
setapikey "$GITHUB_TOKEN" \
-Source "$FEED_URL"
echo "VCPKG_BINARY_SOURCES=clear;nuget,$FEED_URL,readwrite" >> "$GITHUB_ENV"
- name: Setup vcpkg environment
if: ${{ inputs.build-type == 'Debug' }}
shell: bash
run: |
echo "CMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" >> "$GITHUB_ENV"

View file

@ -25,6 +25,40 @@ runs:
arch: ${{ inputs.vcvars-arch }}
vsversion: 2022
- name: Setup Java (MSVC)
uses: actions/setup-java@v5
with:
# NOTE(@getchoo): We should probably stay on Zulu.
# Temurin doesn't have Java 17 builds for WoA
distribution: zulu
java-version: 17
- name: Setup vcpkg cache (MSVC)
if: ${{ inputs.msystem == '' && inputs.build-type == 'Debug' }}
shell: pwsh
env:
USERNAME: ${{ github.repository_owner }}
GITHUB_TOKEN: ${{ github.token }}
FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
run: |
.$(vcpkg fetch nuget) `
sources add `
-Source "$env:FEED_URL" `
-StorePasswordInClearText `
-Name GitHubPackages `
-UserName "$env:USERNAME" `
-Password "$env:GITHUB_TOKEN"
.$(vcpkg fetch nuget) `
setapikey "$env:GITHUB_TOKEN" `
-Source "$env:FEED_URL"
"VCPKG_BINARY_SOURCES=clear;nuget,$env:FEED_URL,readwrite" | Out-File -Append $env:GITHUB_ENV
- name: Setup vcpkg environment (MSVC)
if: ${{ inputs.msystem == '' }}
shell: bash
run: |
echo "CMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" >> "$GITHUB_ENV"
- name: Setup MSYS2 (MinGW)
if: ${{ inputs.msystem != '' }}
uses: msys2/setup-msys2@v2
@ -56,7 +90,7 @@ runs:
- name: Retrieve ccache cache (MinGW)
if: ${{ inputs.msystem != '' && inputs.build-type == 'Debug' }}
uses: actions/cache@v4.2.3
uses: actions/cache@v4.2.4
with:
path: '${{ github.workspace }}\.ccache'
key: ${{ runner.os }}-mingw-w64-ccache-${{ github.run_id }}

View file

@ -21,11 +21,11 @@ jobs:
if: github.repository_owner == 'PrismLauncher' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
uses: korthout/backport-action@v3.2.0
uses: korthout/backport-action@v3.3.0
with:
# Config README: https://github.com/korthout/backport-action#backport-action
pull_description: |-

View file

@ -2,21 +2,23 @@ name: Build
on:
push:
branches-ignore:
- "renovate/**"
branches:
- "develop"
- "release-*"
paths:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -24,21 +26,23 @@ on:
# Workflows
- ".github/workflows/build.yml"
- ".github/actions/package/"
- ".github/actions/setup-dependencies/"
- ".github/actions/package/**"
- ".github/actions/setup-dependencies/**"
pull_request:
paths:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -46,8 +50,8 @@ on:
# Workflows
- ".github/workflows/build.yml"
- ".github/actions/package/"
- ".github/actions/setup-dependencies/"
- ".github/actions/package/**"
- ".github/actions/setup-dependencies/**"
workflow_call:
inputs:
build-type:
@ -65,6 +69,10 @@ jobs:
build:
name: Build (${{ matrix.artifact-name }})
permissions:
# Required for vcpkg binary cache
packages: write
strategy:
fail-fast: false
matrix:
@ -73,6 +81,14 @@ jobs:
artifact-name: Linux
base-cmake-preset: linux
# NOTE(@getchoo): Yes, we're intentionally using 24.04 here!!!
#
# It's not really documented anywhere AFAICT, but upstream Qt binaries
# *for the same version* are compiled against 24.04 on ARM, and *not* 22.04 like x64
- os: ubuntu-24.04-arm
artifact-name: Linux-aarch64
base-cmake-preset: linux
- os: windows-2022
artifact-name: Windows-MinGW-w64
base-cmake-preset: windows_mingw
@ -117,7 +133,7 @@ jobs:
##
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: true
@ -126,6 +142,7 @@ jobs:
uses: ./.github/actions/setup-dependencies
with:
build-type: ${{ inputs.build-type || 'Debug' }}
artifact-name: ${{ matrix.artifact-name }}
msystem: ${{ matrix.msystem }}
vcvars-arch: ${{ matrix.vcvars-arch }}
qt-architecture: ${{ matrix.qt-architecture }}
@ -145,6 +162,9 @@ jobs:
- name: Run CMake workflow
env:
CMAKE_PRESET: ${{ steps.cmake-preset.outputs.preset }}
ARTIFACT_NAME: ${{ matrix.artifact-name }}-Qt6
BUILD_PLATFORM: official
run: |
cmake --workflow --preset "$CMAKE_PRESET"
@ -164,6 +184,7 @@ jobs:
with:
version: ${{ steps.short-version.outputs.version }}
build-type: ${{ steps.setup-dependencies.outputs.build-type }}
artifact-name: ${{ matrix.artifact-name }}
cmake-preset: ${{ steps.cmake-preset.outputs.preset }}
qt-version: ${{ steps.setup-dependencies.outputs.qt-version }}

View file

@ -2,50 +2,56 @@ name: "CodeQL Code Scanning"
on:
push:
branches:
- "develop"
- "release-*"
paths:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
- "COPYING.md"
# Workflows
- ".github/codeql"
- ".github/codeql/**"
- ".github/workflows/codeql.yml"
- ".github/actions/setup-dependencies/"
- ".github/actions/setup-dependencies/**"
pull_request:
paths:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
- "COPYING.md"
# Workflows
- ".github/codeql"
- ".github/codeql/**"
- ".github/workflows/codeql.yml"
- ".github/actions/setup-dependencies/"
- ".github/actions/setup-dependencies/**"
workflow_dispatch:
jobs:
@ -54,7 +60,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: "true"

View file

@ -2,6 +2,9 @@ name: Flatpak
on:
push:
branches:
- "develop"
- "release-*"
# We don't do anything with these artifacts on releases. They go to Flathub
tags-ignore:
- "*"
@ -10,17 +13,18 @@ on:
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Build files
- "flatpak/"
- "flatpak/**"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -33,17 +37,19 @@ on:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Build files
- "flatpak/"
- "flatpak/**"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -78,7 +84,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: true

View file

@ -2,6 +2,9 @@ name: Nix
on:
push:
branches:
- "develop"
- "release-*"
tags:
- "*"
paths:
@ -9,19 +12,20 @@ on:
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Build files
- "**.nix"
- "nix/"
- "nix/**"
- "flake.lock"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -34,19 +38,21 @@ on:
# File types
- "**.cpp"
- "**.h"
- "**.java"
- "**.ui"
# Build files
- "**.nix"
- "nix/"
- "nix/**"
- "flake.lock"
# Directories
- "buildconfig/"
- "cmake/"
- "launcher/"
- "libraries/"
- "program_info/"
- "tests/"
- "buildconfig/**"
- "cmake/**"
- "launcher/**"
- "libraries/**"
- "program_info/**"
- "tests/**"
# Files
- "CMakeLists.txt"
@ -99,12 +105,12 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ steps.merge-commit.outputs.merge-commit-sha || github.sha }}
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v17
uses: DeterminateSystems/nix-installer-action@v19
with:
determinate: ${{ env.USE_DETERMINATE }}

View file

@ -20,12 +20,12 @@ jobs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: "true"
path: "PrismLauncher-source"
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
- name: Grab and store version
run: |
tag_name=$(echo ${{ github.ref }} | grep -oE "[^/]+$")
@ -34,8 +34,10 @@ jobs:
run: |
mv ${{ github.workspace }}/PrismLauncher-source PrismLauncher-${{ env.VERSION }}
mv PrismLauncher-Linux-Qt6-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
mv PrismLauncher-*.AppImage/PrismLauncher-*.AppImage PrismLauncher-Linux-x86_64.AppImage
mv PrismLauncher-*.AppImage.zsync/PrismLauncher-*.AppImage.zsync PrismLauncher-Linux-x86_64.AppImage.zsync
mv PrismLauncher-*.AppImage/PrismLauncher-*-x86_64.AppImage PrismLauncher-Linux-x86_64.AppImage
mv PrismLauncher-*.AppImage.zsync/PrismLauncher-*-x86_64.AppImage.zsync PrismLauncher-Linux-x86_64.AppImage.zsync
mv PrismLauncher-*.AppImage/PrismLauncher-*-aarch64.AppImage PrismLauncher-Linux-aarch64.AppImage
mv PrismLauncher-*.AppImage.zsync/PrismLauncher-*-aarch64.AppImage.zsync PrismLauncher-Linux-aarch64.AppImage.zsync
mv PrismLauncher-macOS*/PrismLauncher.zip PrismLauncher-macOS-${{ env.VERSION }}.zip
tar --exclude='.git' -czf PrismLauncher-${{ env.VERSION }}.tar.gz PrismLauncher-${{ env.VERSION }}
@ -89,7 +91,10 @@ jobs:
files: |
PrismLauncher-Linux-x86_64.AppImage
PrismLauncher-Linux-x86_64.AppImage.zsync
PrismLauncher-Linux-aarch64.AppImage
PrismLauncher-Linux-aarch64.AppImage.zsync
PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
PrismLauncher-Linux-aarch64-Qt6-Portable-${{ env.VERSION }}.tar.gz
PrismLauncher-Windows-MinGW-w64-${{ env.VERSION }}.zip
PrismLauncher-Windows-MinGW-w64-Portable-${{ env.VERSION }}.zip
PrismLauncher-Windows-MinGW-w64-Setup-${{ env.VERSION }}.exe

View file

@ -17,7 +17,7 @@ jobs:
pull-requests: write
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
days-before-stale: 60
days-before-close: -1 # Don't close anything

View file

@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@7be5dee1421f63d07e71ce6e0a9f8a4b07c2a487 # v31
- uses: DeterminateSystems/update-flake-lock@v25
- uses: DeterminateSystems/update-flake-lock@v27
with:
commit-msg: "chore(nix): update lockfile"
pr-title: "chore(nix): update lockfile"

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.15) # minimum version required by QuaZip
cmake_minimum_required(VERSION 3.22) # minimum version required by Qt
project(Launcher)
@ -24,7 +24,7 @@ set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/jars)
######## Set compiler flags ########
set(CMAKE_CXX_STANDARD_REQUIRED true)
set(CMAKE_C_STANDARD_REQUIRED true)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_STANDARD 11)
include(GenerateExportHeader)
if(MSVC)
@ -79,6 +79,19 @@ else()
if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,8388608 ${CMAKE_EXE_LINKER_FLAGS}")
# Emit PDBs for WinDbg, etc.
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--pdb= ${CMAKE_EXE_LINKER_FLAGS}")
foreach(lang C CXX)
set("CMAKE_${lang}_FLAGS" "-gcodeview ${CMAKE_${lang}_FLAGS}")
# Force-enabling this to use generator expressions like TARGET_PDB_FILE
# (and because we can actually emit PDBs)
set("CMAKE_${lang}_LINKER_SUPPORTS_PDB" ON)
endforeach()
endif()
# -ffunction-sections and -fdata-sections help reduce binary size
# -mguard=cf enables Control Flow Guard
# TODO: Look into -gc-sections to further reduce binary size
@ -335,6 +348,14 @@ endif()
if(NOT Launcher_FORCE_BUNDLED_LIBS)
# Find toml++
find_package(tomlplusplus 3.2.0 QUIET)
# Fallback to pkg-config (if available) if CMake files aren't found
if(NOT tomlplusplus_FOUND)
find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(tomlplusplus IMPORTED_TARGET tomlplusplus>=3.2.0)
endif()
endif()
# Find cmark
find_package(cmark QUIET)
@ -372,9 +393,6 @@ if(UNIX AND APPLE)
set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources")
set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars")
# Apps to bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app")
# Mac bundle settings
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_DisplayName}")
set(MACOSX_BUNDLE_INFO_STRING "${Launcher_DisplayName}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.")
@ -391,16 +409,10 @@ if(UNIX AND APPLE)
set(MACOSX_SPARKLE_SHA256 "50612a06038abc931f16011d7903b8326a362c1074dabccb718404ce8e585f0b" CACHE STRING "SHA256 checksum for Sparkle release archive")
set(MACOSX_SPARKLE_DIR "${CMAKE_BINARY_DIR}/frameworks/Sparkle")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${MACOSX_SPARKLE_DIR})
if(NOT MACOSX_SPARKLE_UPDATE_PUBLIC_KEY STREQUAL "" AND NOT MACOSX_SPARKLE_UPDATE_FEED_URL STREQUAL "")
set(Launcher_ENABLE_UPDATER YES)
endif()
# install as bundle
set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies")
# Add the icon
install(FILES ${Launcher_Branding_ICNS} DESTINATION ${RESOURCES_DEST_DIR} RENAME ${Launcher_Name}.icns)
@ -411,9 +423,6 @@ elseif(UNIX)
set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}")
set(JARS_DEST_DIR "share/${Launcher_Name}")
# install as bundle with no dependencies included
set(INSTALL_BUNDLE "nodeps" CACHE STRING "Use fixup_bundle to bundle dependencies")
# Set RPATH
SET(Launcher_BINARY_RPATH "$ORIGIN/")
@ -424,17 +433,9 @@ elseif(UNIX)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/launcher/qtlogging.ini" DESTINATION "share/${Launcher_Name}")
if (INSTALL_BUNDLE STREQUAL full)
set(PLUGIN_DEST_DIR "plugins")
set(BUNDLE_DEST_DIR ".")
set(RESOURCES_DEST_DIR ".")
# Apps to bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${Launcher_APP_BINARY_NAME}")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
set(PLUGIN_DEST_DIR "plugins")
set(BUNDLE_DEST_DIR ".")
set(RESOURCES_DEST_DIR ".")
if(Launcher_ManPage)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_ManPage} DESTINATION "${KDE_INSTALL_MANDIR}/man6")
@ -450,15 +451,6 @@ elseif(WIN32)
set(PLUGIN_DEST_DIR ".")
set(RESOURCES_DEST_DIR ".")
set(JARS_DEST_DIR "jars")
# Apps to bundle
set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.exe")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# install as bundle
set(INSTALL_BUNDLE "full" CACHE STRING "Use fixup_bundle to bundle dependencies")
else()
message(FATAL_ERROR "Platform not supported")
endif()

View file

@ -1,6 +1,6 @@
# Contributions Guidelines
## Code formatting
## Code style
All files are formatted with `clang-format` using the configuration in `.clang-format`. Ensure it is run on changed files before committing!
@ -15,6 +15,11 @@ Please also follow the project's conventions for C++:
- Global functions and non-`const` global variables should be formatted as `camelCase` without a prefix: `globalData`.
- `const` global variables, macros, and enum constants should be formatted as `SCREAMING_SNAKE_CASE`: `LIGHT_GRAY`.
- Avoid inventing acronyms or abbreviations especially for a name of multiple words - like `tp` for `texturePack`.
- Avoid using `[[nodiscard]]` unless ignoring the return value is likely to cause a bug in cases such as:
- A function allocates memory or another resource and the caller needs to clean it up.
- A function has side effects and an error status is returned.
- A function is likely be mistaken for having side effects.
- A plain getter is unlikely to cause confusion and adding `[[nodiscard]]` can create clutter and inconsistency.
Most of these rules are included in the `.clang-tidy` file, so you can run `clang-tidy` to check for any violations.

View file

@ -412,3 +412,26 @@
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.
## vcpkg (`cmake/vcpkg-ports`)
MIT License
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -27,7 +27,7 @@ Please understand that these builds are not intended for most users. There may b
There are development builds available through:
- [GitHub Actions](https://github.com/PrismLauncher/PrismLauncher/actions) (includes builds from pull requests opened by contribuitors)
- [nightly.link](https://nightly.link/PrismLauncher/PrismLauncher/workflows/trigger_builds/develop) (this will always point only to the latest version of develop)
- [nightly.link](https://nightly.link/PrismLauncher/PrismLauncher/workflows/build/develop) (this will always point only to the latest version of develop)
These have debug information in the binaries, so their file sizes are relatively larger.

View file

@ -166,7 +166,7 @@ class Config {
QString DISCORD_URL;
QString SUBREDDIT_URL;
QString RESOURCE_BASE = "https://resources.download.minecraft.net/";
QString DEFAULT_RESOURCE_BASE = "https://resources.download.minecraft.net/";
QString LIBRARY_BASE = "https://libraries.minecraft.net/";
QString IMGUR_BASE_URL = "https://api.imgur.com/3/";
QString FMLLIBS_BASE_URL;

View file

@ -8,7 +8,8 @@
"binaryDir": "build",
"installDir": "install",
"cacheVariables": {
"Launcher_BUILD_PLATFORM": "custom"
"Launcher_BUILD_ARTIFACT": "$penv{ARTIFACT_NAME}",
"Launcher_BUILD_PLATFORM": "$penv{BUILD_PLATFORM}"
}
},
{
@ -39,7 +40,6 @@
"base_release"
],
"cacheVariables": {
"Launcher_BUILD_PLATFORM": "official",
"Launcher_FORCE_BUNDLED_LIBS": "ON"
}
}

View file

@ -15,7 +15,6 @@
},
"generator": "Ninja",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Linux-Qt6",
"Launcher_ENABLE_JAVA_DOWNLOADER": "ON"
}
},
@ -42,9 +41,6 @@
"linux_base"
],
"displayName": "Linux (CI)",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Linux-Qt6"
},
"installDir": "/usr"
}
],

View file

@ -23,7 +23,7 @@
],
"cacheVariables": {
"CMAKE_OSX_ARCHITECTURES": "x86_64;arm64",
"Launcher_BUILD_ARTIFACT": "macOS-Qt6"
"VCPKG_TARGET_TRIPLET": "universal-osx"
}
},
{
@ -64,10 +64,7 @@
"base_ci",
"macos_universal_base"
],
"displayName": "macOS (CI)",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "macOS-Qt6"
}
"displayName": "macOS (CI)"
}
],
"buildPresets": [

View file

@ -0,0 +1,3 @@
The only difference between this and the upstream vcpkg port is the addition of `universal-osx.patch`. It's very annoying we need to bundle this entire tree to do that.
-@getchoo

View file

@ -0,0 +1,13 @@
diff --git a/mesonbuild/cmake/toolchain.py b/mesonbuild/cmake/toolchain.py
index 11a00be5d..89ae490ff 100644
--- a/mesonbuild/cmake/toolchain.py
+++ b/mesonbuild/cmake/toolchain.py
@@ -202,7 +202,7 @@ class CMakeToolchain:
@staticmethod
def is_cmdline_option(compiler: 'Compiler', arg: str) -> bool:
if compiler.get_argument_syntax() == 'msvc':
- return arg.startswith('/')
+ return arg.startswith(('/','-'))
else:
if os.path.basename(compiler.get_exe()) == 'zig' and arg in {'ar', 'cc', 'c++', 'dlltool', 'lib', 'ranlib', 'objcopy', 'rc'}:
return True

View file

@ -0,0 +1,45 @@
diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py
index 883a29a..d9a82af 100644
--- a/mesonbuild/dependencies/python.py
+++ b/mesonbuild/dependencies/python.py
@@ -232,8 +232,10 @@ class _PythonDependencyBase(_Base):
else:
if self.is_freethreaded:
libpath = Path('libs') / f'python{vernum}t.lib'
+ libpath = Path('libs') / f'..' / f'..' / f'..' / f'lib' / f'python{vernum}t.lib'
else:
libpath = Path('libs') / f'python{vernum}.lib'
+ libpath = Path('libs') / f'..' / f'..' / f'..' / f'lib' / f'python{vernum}.lib'
# For a debug build, pyconfig.h may force linking with
# pythonX_d.lib (see meson#10776). This cannot be avoided
# and won't work unless we also have a debug build of
@@ -250,6 +252,8 @@ class _PythonDependencyBase(_Base):
vscrt = self.env.coredata.optstore.get_value('b_vscrt')
if vscrt in {'mdd', 'mtd', 'from_buildtype', 'static_from_buildtype'}:
vscrt_debug = True
+ if is_debug_build:
+ libpath = Path('libs') / f'..' / f'..' / f'..' / f'debug/lib' / f'python{vernum}_d.lib'
if is_debug_build and vscrt_debug and not self.variables.get('Py_DEBUG'):
mlog.warning(textwrap.dedent('''\
Using a debug build type with MSVC or an MSVC-compatible compiler
@@ -350,9 +354,10 @@ class PythonSystemDependency(SystemDependency, _PythonDependencyBase):
self.is_found = True
# compile args
+ verdot = self.variables.get('py_version_short')
inc_paths = mesonlib.OrderedSet([
self.variables.get('INCLUDEPY'),
- self.paths.get('include'),
+ self.paths.get('include') + f'/../../../include/python${verdot}',
self.paths.get('platinclude')])
self.compile_args += ['-I' + path for path in inc_paths if path]
@@ -416,7 +421,7 @@ def python_factory(env: 'Environment', for_machine: 'MachineChoice',
candidates.append(functools.partial(wrap_in_pythons_pc_dir, pkg_name, env, kwargs, installation))
# We only need to check both, if a python install has a LIBPC. It might point to the wrong location,
# e.g. relocated / cross compilation, but the presence of LIBPC indicates we should definitely look for something.
- if pkg_libdir is not None:
+ if True or pkg_libdir is not None:
candidates.append(functools.partial(PythonPkgConfigDependency, pkg_name, env, kwargs, installation))
else:
candidates.append(functools.partial(PkgConfigDependency, 'python3', env, kwargs))

View file

@ -0,0 +1,52 @@
From a16ec8b0fb6d7035b669a13edd4d97ff0c307a0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20D=C3=B8rum?= <martid0311@gmail.com>
Date: Fri, 2 May 2025 10:56:28 +0200
Subject: [PATCH] cpp: fix _LIBCPP_ENABLE_ASSERTIONS warning
libc++ deprecated _LIBCPP_ENABLE_ASSERTIONS from version 18.
However, the libc++ shipped with Apple Clang backported that
deprecation in version 17 already,
which is the version which Apple currently ships for macOS.
This PR changes the _LIBCPP_ENABLE_ASSERTIONS deprecation check
to use version ">=17" on Apple Clang.
---
mesonbuild/compilers/cpp.py | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 01b9bb9fa34f..f7dc150e8608 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -311,6 +311,9 @@ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subpro
return libs
return []
+ def is_libcpp_enable_assertions_deprecated(self) -> bool:
+ return version_compare(self.version, ">=18")
+
def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
if disable:
return ['-DNDEBUG']
@@ -323,7 +326,7 @@ def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
if self.language_stdlib_provider(env) == 'stdc++':
return ['-D_GLIBCXX_ASSERTIONS=1']
else:
- if version_compare(self.version, '>=18'):
+ if self.is_libcpp_enable_assertions_deprecated():
return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']
elif version_compare(self.version, '>=15'):
return ['-D_LIBCPP_ENABLE_ASSERTIONS=1']
@@ -343,7 +346,12 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler):
class AppleClangCPPCompiler(AppleCompilerMixin, AppleCPPStdsMixin, ClangCPPCompiler):
- pass
+ def is_libcpp_enable_assertions_deprecated(self) -> bool:
+ # Upstream libc++ deprecated _LIBCPP_ENABLE_ASSERTIONS
+ # in favor of _LIBCPP_HARDENING_MODE from version 18 onwards,
+ # but Apple Clang 17's libc++ has back-ported that change.
+ # See: https://github.com/mesonbuild/meson/issues/14440
+ return version_compare(self.version, ">=17")
class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):

View file

@ -0,0 +1,5 @@
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/meson")
file(INSTALL "${SOURCE_PATH}/meson.py"
"${SOURCE_PATH}/mesonbuild"
DESTINATION "${CURRENT_PACKAGES_DIR}/tools/meson"
)

View file

@ -0,0 +1,13 @@
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -593,7 +593,8 @@ iconv_factory = DependencyFactory(
packages['intl'] = intl_factory = DependencyFactory(
'intl',
+ [DependencyMethods.BUILTIN, DependencyMethods.SYSTEM, DependencyMethods.CMAKE],
+ cmake_name='Intl',
- [DependencyMethods.BUILTIN, DependencyMethods.SYSTEM],
builtin_class=IntlBuiltinDependency,
system_class=IntlSystemDependency,
)

View file

@ -0,0 +1,43 @@
[binaries]
cmake = ['@CMAKE_COMMAND@']
ninja = ['@NINJA@']
pkg-config = ['@PKGCONFIG@']
@MESON_MT@
@MESON_AR@
@MESON_RC@
@MESON_C@
@MESON_C_LD@
@MESON_CXX@
@MESON_CXX_LD@
@MESON_OBJC@
@MESON_OBJC_LD@
@MESON_OBJCPP@
@MESON_OBJCPP_LD@
@MESON_FC@
@MESON_FC_LD@
@MESON_WINDRES@
@MESON_ADDITIONAL_BINARIES@
[properties]
cmake_toolchain_file = '@SCRIPTS@/buildsystems/vcpkg.cmake'
@MESON_ADDITIONAL_PROPERTIES@
[cmake]
CMAKE_BUILD_TYPE = '@MESON_CMAKE_BUILD_TYPE@'
VCPKG_TARGET_TRIPLET = '@TARGET_TRIPLET@'
VCPKG_HOST_TRIPLET = '@_HOST_TRIPLET@'
VCPKG_CHAINLOAD_TOOLCHAIN_FILE = '@VCPKG_CHAINLOAD_TOOLCHAIN_FILE@'
VCPKG_CRT_LINKAGE = '@VCPKG_CRT_LINKAGE@'
_VCPKG_INSTALLED_DIR = '@_VCPKG_INSTALLED_DIR@'
@MESON_HOST_MACHINE@
@MESON_BUILD_MACHINE@
[built-in options]
default_library = '@MESON_DEFAULT_LIBRARY@'
werror = false
@MESON_CFLAGS@
@MESON_CXXFLAGS@
@MESON_FCFLAGS@
@MESON_OBJCFLAGS@
@MESON_OBJCPPFLAGS@
# b_vscrt
@MESON_VSCRT_LINKAGE@
# c_winlibs/cpp_winlibs
@MESON_WINLIBS@

View file

@ -0,0 +1,45 @@
# This port represents a dependency on the Meson build system.
# In the future, it is expected that this port acquires and installs Meson.
# Currently is used in ports that call vcpkg_find_acquire_program(MESON) in order to force rebuilds.
set(VCPKG_POLICY_CMAKE_HELPER_PORT enabled)
set(patches
meson-intl.patch
adjust-python-dep.patch
adjust-args.patch
remove-freebsd-pcfile-specialization.patch
fix-libcpp-enable-assertions.patch # https://github.com/mesonbuild/meson/pull/14548, Remove in 1.8.3
universal-osx.patch # NOTE(@getchoo): THIS IS THE ONLY CHANGE NEEDED FOR PRISM
)
set(scripts
vcpkg-port-config.cmake
vcpkg_configure_meson.cmake
vcpkg_install_meson.cmake
meson.template.in
)
set(to_hash
"${CMAKE_CURRENT_LIST_DIR}/vcpkg.json"
"${CMAKE_CURRENT_LIST_DIR}/portfile.cmake"
)
foreach(file IN LISTS patches scripts)
set(filepath "${CMAKE_CURRENT_LIST_DIR}/${file}")
list(APPEND to_hash "${filepath}")
file(COPY "${filepath}" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
endforeach()
set(meson_path_hash "")
foreach(filepath IN LISTS to_hash)
file(SHA1 "${filepath}" to_append)
string(APPEND meson_path_hash "${to_append}")
endforeach()
string(SHA512 meson_path_hash "${meson_path_hash}")
string(SUBSTRING "${meson_path_hash}" 0 6 MESON_SHORT_HASH)
list(TRANSFORM patches REPLACE [[^(..*)$]] [["${CMAKE_CURRENT_LIST_DIR}/\0"]])
list(JOIN patches "\n " PATCHES)
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-port-config.cmake" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-port-config.cmake" @ONLY)
vcpkg_install_copyright(FILE_LIST "${VCPKG_ROOT_DIR}/LICENSE.txt")
include("${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-port-config.cmake")

View file

@ -0,0 +1,23 @@
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index cc0450a52..13501466d 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -701,16 +701,8 @@ class PkgConfigModule(NewExtensionModule):
pcfile = filebase + '.pc'
pkgroot = pkgroot_name = kwargs['install_dir'] or default_install_dir
if pkgroot is None:
- m = state.environment.machines.host
- if m.is_freebsd():
- pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'))), 'libdata', 'pkgconfig')
- pkgroot_name = os.path.join('{prefix}', 'libdata', 'pkgconfig')
- elif m.is_haiku():
- pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'))), 'develop', 'lib', 'pkgconfig')
- pkgroot_name = os.path.join('{prefix}', 'develop', 'lib', 'pkgconfig')
- else:
- pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('libdir'))), 'pkgconfig')
- pkgroot_name = os.path.join('{libdir}', 'pkgconfig')
+ pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('libdir'))), 'pkgconfig')
+ pkgroot_name = os.path.join('{libdir}', 'pkgconfig')
relocatable = state.get_option('pkgconfig.relocatable')
self._generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables,

View file

@ -0,0 +1,16 @@
diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py
index f57957f0b..a72e72a0b 100644
--- a/mesonbuild/compilers/detect.py
+++ b/mesonbuild/compilers/detect.py
@@ -1472,6 +1472,11 @@ def _get_clang_compiler_defines(compiler: T.List[str], lang: str) -> T.Dict[str,
"""
from .mixins.clang import clang_lang_map
+ # Filter out `-arch` flags passed to the compiler for Universal Binaries
+ # https://github.com/mesonbuild/meson/issues/5290
+ # https://github.com/mesonbuild/meson/issues/8206
+ compiler = [arg for i, arg in enumerate(compiler) if not (i > 0 and compiler[i - 1] == "-arch") and not arg == "-arch"]
+
def _try_obtain_compiler_defines(args: T.List[str]) -> str:
mlog.debug(f'Running command: {join_args(args)}')
p, output, error = Popen_safe(compiler + args, write='', stdin=subprocess.PIPE)

View file

@ -0,0 +1,62 @@
include("${CURRENT_HOST_INSTALLED_DIR}/share/vcpkg-cmake-get-vars/vcpkg-port-config.cmake")
# Overwrite builtin scripts
include("${CMAKE_CURRENT_LIST_DIR}/vcpkg_configure_meson.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/vcpkg_install_meson.cmake")
set(meson_short_hash @MESON_SHORT_HASH@)
# Setup meson:
set(program MESON)
set(program_version @VERSION@)
set(program_name meson)
set(search_names meson meson.py)
set(ref "${program_version}")
set(path_to_search "${DOWNLOADS}/tools/meson-${program_version}-${meson_short_hash}")
set(download_urls "https://github.com/mesonbuild/meson/archive/${ref}.tar.gz")
set(download_filename "meson-${ref}.tar.gz")
set(download_sha512 bd2e65f0863d9cb974e659ff502d773e937b8a60aaddfd7d81e34cd2c296c8e82bf214d790ac089ba441543059dfc2677ba95ed51f676df9da420859f404a907)
find_program(SCRIPT_MESON NAMES ${search_names} PATHS "${path_to_search}" NO_DEFAULT_PATH) # NO_DEFAULT_PATH due top patching
if(NOT SCRIPT_MESON)
vcpkg_download_distfile(archive_path
URLS ${download_urls}
SHA512 "${download_sha512}"
FILENAME "${download_filename}"
)
file(REMOVE_RECURSE "${path_to_search}")
file(REMOVE_RECURSE "${path_to_search}-tmp")
file(MAKE_DIRECTORY "${path_to_search}-tmp")
file(ARCHIVE_EXTRACT INPUT "${archive_path}"
DESTINATION "${path_to_search}-tmp"
#PATTERNS "**/mesonbuild/*" "**/*.py"
)
z_vcpkg_apply_patches(
SOURCE_PATH "${path_to_search}-tmp/meson-${ref}"
PATCHES
@PATCHES@
)
file(MAKE_DIRECTORY "${path_to_search}")
file(RENAME "${path_to_search}-tmp/meson-${ref}/meson.py" "${path_to_search}/meson.py")
file(RENAME "${path_to_search}-tmp/meson-${ref}/mesonbuild" "${path_to_search}/mesonbuild")
file(REMOVE_RECURSE "${path_to_search}-tmp")
set(SCRIPT_MESON "${path_to_search}/meson.py")
endif()
# Check required python version
vcpkg_find_acquire_program(PYTHON3)
vcpkg_execute_in_download_mode(
COMMAND "${PYTHON3}" --version
OUTPUT_VARIABLE version_contents
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}"
)
string(REGEX MATCH [[[0-9]+\.[0-9]+\.[0-9]+]] python_ver "${version_contents}")
set(min_required 3.7)
if(python_ver VERSION_LESS "${min_required}")
message(FATAL_ERROR "Found Python version '${python_ver} at ${PYTHON3}' is insufficient for meson. meson requires at least version '${min_required}'")
else()
message(STATUS "Found Python version '${python_ver} at ${PYTHON3}'")
endif()
message(STATUS "Using meson: ${SCRIPT_MESON}")

View file

@ -0,0 +1,11 @@
{
"name": "vcpkg-tool-meson",
"version": "1.8.2",
"description": "Meson build system",
"homepage": "https://github.com/mesonbuild/meson",
"license": "Apache-2.0",
"supports": "native",
"dependencies": [
"vcpkg-cmake-get-vars"
]
}

View file

@ -0,0 +1,480 @@
function(z_vcpkg_meson_set_proglist_variables config_type)
if(VCPKG_TARGET_IS_WINDOWS)
set(proglist MT AR)
else()
set(proglist AR RANLIB STRIP NM OBJDUMP DLLTOOL MT)
endif()
foreach(prog IN LISTS proglist)
if(VCPKG_DETECTED_CMAKE_${prog})
if(meson_${prog})
string(TOUPPER "MESON_${meson_${prog}}" var_to_set)
set("${var_to_set}" "${meson_${prog}} = ['${VCPKG_DETECTED_CMAKE_${prog}}']" PARENT_SCOPE)
elseif(${prog} STREQUAL AR AND VCPKG_COMBINED_STATIC_LINKER_FLAGS_${config_type})
# Probably need to move AR somewhere else
string(TOLOWER "${prog}" proglower)
z_vcpkg_meson_convert_compiler_flags_to_list(ar_flags "${VCPKG_COMBINED_STATIC_LINKER_FLAGS_${config_type}}")
list(PREPEND ar_flags "${VCPKG_DETECTED_CMAKE_${prog}}")
z_vcpkg_meson_convert_list_to_python_array(ar_flags ${ar_flags})
set("MESON_AR" "${proglower} = ${ar_flags}" PARENT_SCOPE)
else()
string(TOUPPER "MESON_${prog}" var_to_set)
string(TOLOWER "${prog}" proglower)
set("${var_to_set}" "${proglower} = ['${VCPKG_DETECTED_CMAKE_${prog}}']" PARENT_SCOPE)
endif()
endif()
endforeach()
set(compilers "${arg_LANGUAGES}")
if(VCPKG_TARGET_IS_WINDOWS)
list(APPEND compilers RC)
endif()
set(meson_RC windres)
set(meson_Fortran fortran)
set(meson_CXX cpp)
foreach(prog IN LISTS compilers)
if(VCPKG_DETECTED_CMAKE_${prog}_COMPILER)
string(TOUPPER "MESON_${prog}" var_to_set)
if(meson_${prog})
if(VCPKG_COMBINED_${prog}_FLAGS_${config_type})
# Need compiler flags in prog vars for sanity check.
z_vcpkg_meson_convert_compiler_flags_to_list(${prog}flags "${VCPKG_COMBINED_${prog}_FLAGS_${config_type}}")
endif()
list(PREPEND ${prog}flags "${VCPKG_DETECTED_CMAKE_${prog}_COMPILER}")
list(FILTER ${prog}flags EXCLUDE REGEX "(-|/)nologo") # Breaks compiler detection otherwise
z_vcpkg_meson_convert_list_to_python_array(${prog}flags ${${prog}flags})
set("${var_to_set}" "${meson_${prog}} = ${${prog}flags}" PARENT_SCOPE)
if (DEFINED VCPKG_DETECTED_CMAKE_${prog}_COMPILER_ID
AND NOT VCPKG_DETECTED_CMAKE_${prog}_COMPILER_ID MATCHES "^(GNU|Intel)$"
AND VCPKG_DETECTED_CMAKE_LINKER)
string(TOUPPER "MESON_${prog}_LD" var_to_set)
set(${var_to_set} "${meson_${prog}}_ld = ['${VCPKG_DETECTED_CMAKE_LINKER}']" PARENT_SCOPE)
endif()
else()
if(VCPKG_COMBINED_${prog}_FLAGS_${config_type})
# Need compiler flags in prog vars for sanity check.
z_vcpkg_meson_convert_compiler_flags_to_list(${prog}flags "${VCPKG_COMBINED_${prog}_FLAGS_${config_type}}")
endif()
list(PREPEND ${prog}flags "${VCPKG_DETECTED_CMAKE_${prog}_COMPILER}")
list(FILTER ${prog}flags EXCLUDE REGEX "(-|/)nologo") # Breaks compiler detection otherwise
z_vcpkg_meson_convert_list_to_python_array(${prog}flags ${${prog}flags})
string(TOLOWER "${prog}" proglower)
set("${var_to_set}" "${proglower} = ${${prog}flags}" PARENT_SCOPE)
if (DEFINED VCPKG_DETECTED_CMAKE_${prog}_COMPILER_ID
AND NOT VCPKG_DETECTED_CMAKE_${prog}_COMPILER_ID MATCHES "^(GNU|Intel)$"
AND VCPKG_DETECTED_CMAKE_LINKER)
string(TOUPPER "MESON_${prog}_LD" var_to_set)
set(${var_to_set} "${proglower}_ld = ['${VCPKG_DETECTED_CMAKE_LINKER}']" PARENT_SCOPE)
endif()
endif()
endif()
endforeach()
endfunction()
function(z_vcpkg_meson_convert_compiler_flags_to_list out_var compiler_flags)
separate_arguments(cmake_list NATIVE_COMMAND "${compiler_flags}")
list(TRANSFORM cmake_list REPLACE ";" [[\\;]])
set("${out_var}" "${cmake_list}" PARENT_SCOPE)
endfunction()
function(z_vcpkg_meson_convert_list_to_python_array out_var)
z_vcpkg_function_arguments(flag_list 1)
vcpkg_list(REMOVE_ITEM flag_list "") # remove empty elements if any
vcpkg_list(JOIN flag_list "', '" flag_list)
set("${out_var}" "['${flag_list}']" PARENT_SCOPE)
endfunction()
# Generates the required compiler properties for meson
function(z_vcpkg_meson_set_flags_variables config_type)
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
set(libpath_flag /LIBPATH:)
else()
set(libpath_flag -L)
endif()
if(config_type STREQUAL "DEBUG")
set(path_suffix "/debug")
else()
set(path_suffix "")
endif()
set(includepath "-I${CURRENT_INSTALLED_DIR}/include")
set(libpath "${libpath_flag}${CURRENT_INSTALLED_DIR}${path_suffix}/lib")
foreach(lang IN LISTS arg_LANGUAGES)
z_vcpkg_meson_convert_compiler_flags_to_list(${lang}flags "${VCPKG_COMBINED_${lang}_FLAGS_${config_type}}")
if(lang MATCHES "^(C|CXX)$")
vcpkg_list(APPEND ${lang}flags "${includepath}")
endif()
z_vcpkg_meson_convert_list_to_python_array(${lang}flags ${${lang}flags})
set(lang_mapping "${lang}")
if(lang STREQUAL "Fortran")
set(lang_mapping "FC")
endif()
string(TOLOWER "${lang_mapping}" langlower)
if(lang STREQUAL "CXX")
set(langlower cpp)
endif()
set(MESON_${lang_mapping}FLAGS "${langlower}_args = ${${lang}flags}\n")
set(linker_flags "${VCPKG_COMBINED_SHARED_LINKER_FLAGS_${config_type}}")
z_vcpkg_meson_convert_compiler_flags_to_list(linker_flags "${linker_flags}")
vcpkg_list(APPEND linker_flags "${libpath}")
z_vcpkg_meson_convert_list_to_python_array(linker_flags ${linker_flags})
string(APPEND MESON_${lang_mapping}FLAGS "${langlower}_link_args = ${linker_flags}\n")
set(MESON_${lang_mapping}FLAGS "${MESON_${lang_mapping}FLAGS}" PARENT_SCOPE)
endforeach()
endfunction()
function(z_vcpkg_get_build_and_host_system build_system host_system is_cross) #https://mesonbuild.com/Cross-compilation.html
set(build_unknown FALSE)
if(CMAKE_HOST_WIN32)
if(DEFINED ENV{PROCESSOR_ARCHITEW6432})
set(build_arch $ENV{PROCESSOR_ARCHITEW6432})
else()
set(build_arch $ENV{PROCESSOR_ARCHITECTURE})
endif()
if(build_arch MATCHES "(amd|AMD)64")
set(build_cpu_fam x86_64)
set(build_cpu x86_64)
elseif(build_arch MATCHES "(x|X)86")
set(build_cpu_fam x86)
set(build_cpu i686)
elseif(build_arch MATCHES "^(ARM|arm)64$")
set(build_cpu_fam aarch64)
set(build_cpu armv8)
elseif(build_arch MATCHES "^(ARM|arm)$")
set(build_cpu_fam arm)
set(build_cpu armv7hl)
else()
if(NOT DEFINED VCPKG_MESON_CROSS_FILE OR NOT DEFINED VCPKG_MESON_NATIVE_FILE)
message(WARNING "Unsupported build architecture ${build_arch}! Please set VCPKG_MESON_(CROSS|NATIVE)_FILE to a meson file containing the build_machine entry!")
endif()
set(build_unknown TRUE)
endif()
elseif(CMAKE_HOST_UNIX)
# at this stage, CMAKE_HOST_SYSTEM_PROCESSOR is not defined
execute_process(
COMMAND uname -m
OUTPUT_VARIABLE MACHINE
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY)
# Show real machine architecture to visually understand whether we are in a native Apple Silicon terminal or running under Rosetta emulation
debug_message("Machine: ${MACHINE}")
if(MACHINE MATCHES "arm64|aarch64")
set(build_cpu_fam aarch64)
set(build_cpu armv8)
elseif(MACHINE MATCHES "armv7h?l")
set(build_cpu_fam arm)
set(build_cpu ${MACHINE})
elseif(MACHINE MATCHES "x86_64|amd64")
set(build_cpu_fam x86_64)
set(build_cpu x86_64)
elseif(MACHINE MATCHES "x86|i686")
set(build_cpu_fam x86)
set(build_cpu i686)
elseif(MACHINE MATCHES "i386")
set(build_cpu_fam x86)
set(build_cpu i386)
elseif(MACHINE MATCHES "loongarch64")
set(build_cpu_fam loongarch64)
set(build_cpu loongarch64)
else()
# https://github.com/mesonbuild/meson/blob/master/docs/markdown/Reference-tables.md#cpu-families
if(NOT DEFINED VCPKG_MESON_CROSS_FILE OR NOT DEFINED VCPKG_MESON_NATIVE_FILE)
message(WARNING "Unhandled machine: ${MACHINE}! Please set VCPKG_MESON_(CROSS|NATIVE)_FILE to a meson file containing the build_machine entry!")
endif()
set(build_unknown TRUE)
endif()
else()
if(NOT DEFINED VCPKG_MESON_CROSS_FILE OR NOT DEFINED VCPKG_MESON_NATIVE_FILE)
message(WARNING "Failed to detect the build architecture! Please set VCPKG_MESON_(CROSS|NATIVE)_FILE to a meson file containing the build_machine entry!")
endif()
set(build_unknown TRUE)
endif()
set(build "[build_machine]\n") # Machine the build is performed on
string(APPEND build "endian = 'little'\n")
if(CMAKE_HOST_WIN32)
string(APPEND build "system = 'windows'\n")
elseif(CMAKE_HOST_APPLE)
string(APPEND build "system = 'darwin'\n")
elseif(CYGWIN)
string(APPEND build "system = 'cygwin'\n")
elseif(CMAKE_HOST_UNIX)
string(APPEND build "system = 'linux'\n")
else()
set(build_unknown TRUE)
endif()
if(DEFINED build_cpu_fam)
string(APPEND build "cpu_family = '${build_cpu_fam}'\n")
endif()
if(DEFINED build_cpu)
string(APPEND build "cpu = '${build_cpu}'")
endif()
if(NOT build_unknown)
set(${build_system} "${build}" PARENT_SCOPE)
endif()
set(host_unkown FALSE)
if(VCPKG_TARGET_ARCHITECTURE MATCHES "(amd|AMD|x|X)64")
set(host_cpu_fam x86_64)
set(host_cpu x86_64)
elseif(VCPKG_TARGET_ARCHITECTURE MATCHES "(x|X)86")
set(host_cpu_fam x86)
set(host_cpu i686)
elseif(VCPKG_TARGET_ARCHITECTURE MATCHES "^(ARM|arm)64$")
set(host_cpu_fam aarch64)
set(host_cpu armv8)
elseif(VCPKG_TARGET_ARCHITECTURE MATCHES "^(ARM|arm)$")
set(host_cpu_fam arm)
set(host_cpu armv7hl)
elseif(VCPKG_TARGET_ARCHITECTURE MATCHES "loongarch64")
set(host_cpu_fam loongarch64)
set(host_cpu loongarch64)
elseif(VCPKG_TARGET_ARCHITECTURE MATCHES "wasm32")
set(host_cpu_fam wasm32)
set(host_cpu wasm32)
else()
if(NOT DEFINED VCPKG_MESON_CROSS_FILE OR NOT DEFINED VCPKG_MESON_NATIVE_FILE)
message(WARNING "Unsupported target architecture ${VCPKG_TARGET_ARCHITECTURE}! Please set VCPKG_MESON_(CROSS|NATIVE)_FILE to a meson file containing the host_machine entry!" )
endif()
set(host_unkown TRUE)
endif()
set(host "[host_machine]\n") # host=target in vcpkg.
string(APPEND host "endian = 'little'\n")
if(NOT VCPKG_CMAKE_SYSTEM_NAME OR VCPKG_TARGET_IS_MINGW OR VCPKG_TARGET_IS_UWP)
set(meson_system_name "windows")
else()
string(TOLOWER "${VCPKG_CMAKE_SYSTEM_NAME}" meson_system_name)
endif()
string(APPEND host "system = '${meson_system_name}'\n")
string(APPEND host "cpu_family = '${host_cpu_fam}'\n")
string(APPEND host "cpu = '${host_cpu}'")
if(NOT host_unkown)
set(${host_system} "${host}" PARENT_SCOPE)
endif()
if(NOT build_cpu_fam MATCHES "${host_cpu_fam}"
OR VCPKG_TARGET_IS_ANDROID OR VCPKG_TARGET_IS_IOS OR VCPKG_TARGET_IS_UWP
OR (VCPKG_TARGET_IS_MINGW AND NOT CMAKE_HOST_WIN32))
set(${is_cross} TRUE PARENT_SCOPE)
endif()
endfunction()
function(z_vcpkg_meson_setup_extra_windows_variables config_type)
## b_vscrt
if(VCPKG_CRT_LINKAGE STREQUAL "static")
set(crt_type "mt")
else()
set(crt_type "md")
endif()
if(config_type STREQUAL "DEBUG")
set(crt_type "${crt_type}d")
endif()
set(MESON_VSCRT_LINKAGE "b_vscrt = '${crt_type}'" PARENT_SCOPE)
## winlibs
separate_arguments(c_winlibs NATIVE_COMMAND "${VCPKG_DETECTED_CMAKE_C_STANDARD_LIBRARIES}")
separate_arguments(cpp_winlibs NATIVE_COMMAND "${VCPKG_DETECTED_CMAKE_CXX_STANDARD_LIBRARIES}")
z_vcpkg_meson_convert_list_to_python_array(c_winlibs ${c_winlibs})
z_vcpkg_meson_convert_list_to_python_array(cpp_winlibs ${cpp_winlibs})
set(MESON_WINLIBS "c_winlibs = ${c_winlibs}\n")
string(APPEND MESON_WINLIBS "cpp_winlibs = ${cpp_winlibs}")
set(MESON_WINLIBS "${MESON_WINLIBS}" PARENT_SCOPE)
endfunction()
function(z_vcpkg_meson_setup_variables config_type)
set(meson_var_list VSCRT_LINKAGE WINLIBS MT AR RC C C_LD CXX CXX_LD OBJC OBJC_LD OBJCXX OBJCXX_LD FC FC_LD WINDRES CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS FCFLAGS SHARED_LINKER_FLAGS)
foreach(var IN LISTS meson_var_list)
set(MESON_${var} "")
endforeach()
if(VCPKG_TARGET_IS_WINDOWS)
z_vcpkg_meson_setup_extra_windows_variables("${config_type}")
endif()
z_vcpkg_meson_set_proglist_variables("${config_type}")
z_vcpkg_meson_set_flags_variables("${config_type}")
foreach(var IN LISTS meson_var_list)
set(MESON_${var} "${MESON_${var}}" PARENT_SCOPE)
endforeach()
endfunction()
function(vcpkg_generate_meson_cmd_args)
cmake_parse_arguments(PARSE_ARGV 0 arg
""
"OUTPUT;CONFIG"
"OPTIONS;LANGUAGES;ADDITIONAL_BINARIES;ADDITIONAL_PROPERTIES"
)
if(NOT arg_LANGUAGES)
set(arg_LANGUAGES C CXX)
endif()
vcpkg_list(JOIN arg_ADDITIONAL_BINARIES "\n" MESON_ADDITIONAL_BINARIES)
vcpkg_list(JOIN arg_ADDITIONAL_PROPERTIES "\n" MESON_ADDITIONAL_PROPERTIES)
set(buildtype "${arg_CONFIG}")
if(NOT VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
z_vcpkg_select_default_vcpkg_chainload_toolchain()
endif()
vcpkg_list(APPEND VCPKG_CMAKE_CONFIGURE_OPTIONS "-DVCPKG_LANGUAGES=${arg_LANGUAGES}")
vcpkg_cmake_get_vars(cmake_vars_file)
debug_message("Including cmake vars from: ${cmake_vars_file}")
include("${cmake_vars_file}")
vcpkg_list(APPEND arg_OPTIONS --backend ninja --wrap-mode nodownload -Doptimization=plain)
z_vcpkg_get_build_and_host_system(MESON_HOST_MACHINE MESON_BUILD_MACHINE IS_CROSS)
if(arg_CONFIG STREQUAL "DEBUG")
set(suffix "dbg")
else()
string(SUBSTRING "${arg_CONFIG}" 0 3 suffix)
string(TOLOWER "${suffix}" suffix)
endif()
set(meson_input_file_${buildtype} "${CURRENT_BUILDTREES_DIR}/meson-${TARGET_TRIPLET}-${suffix}.log")
if(IS_CROSS)
# VCPKG_CROSSCOMPILING is not used since it regresses a lot of ports in x64-windows-x triplets
# For consistency this should proably be changed in the future?
vcpkg_list(APPEND arg_OPTIONS --native "${SCRIPTS}/buildsystems/meson/none.txt")
vcpkg_list(APPEND arg_OPTIONS --cross "${meson_input_file_${buildtype}}")
else()
vcpkg_list(APPEND arg_OPTIONS --native "${meson_input_file_${buildtype}}")
endif()
# User provided cross/native files
if(VCPKG_MESON_NATIVE_FILE)
vcpkg_list(APPEND arg_OPTIONS --native "${VCPKG_MESON_NATIVE_FILE}")
endif()
if(VCPKG_MESON_NATIVE_FILE_${buildtype})
vcpkg_list(APPEND arg_OPTIONS --native "${VCPKG_MESON_NATIVE_FILE_${buildtype}}")
endif()
if(VCPKG_MESON_CROSS_FILE)
vcpkg_list(APPEND arg_OPTIONS --cross "${VCPKG_MESON_CROSS_FILE}")
endif()
if(VCPKG_MESON_CROSS_FILE_${buildtype})
vcpkg_list(APPEND arg_OPTIONS --cross "${VCPKG_MESON_CROSS_FILE_${buildtype}}")
endif()
vcpkg_list(APPEND arg_OPTIONS --libdir lib) # else meson install into an architecture describing folder
vcpkg_list(APPEND arg_OPTIONS --pkgconfig.relocatable)
if(arg_CONFIG STREQUAL "RELEASE")
vcpkg_list(APPEND arg_OPTIONS -Ddebug=false --prefix "${CURRENT_PACKAGES_DIR}")
vcpkg_list(APPEND arg_OPTIONS "--pkg-config-path;['${CURRENT_INSTALLED_DIR}/lib/pkgconfig','${CURRENT_INSTALLED_DIR}/share/pkgconfig']")
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_list(APPEND arg_OPTIONS "-Dcmake_prefix_path=['${CURRENT_INSTALLED_DIR}','${CURRENT_INSTALLED_DIR}/debug','${CURRENT_INSTALLED_DIR}/share']")
else()
vcpkg_list(APPEND arg_OPTIONS "-Dcmake_prefix_path=['${CURRENT_INSTALLED_DIR}','${CURRENT_INSTALLED_DIR}/debug']")
endif()
elseif(arg_CONFIG STREQUAL "DEBUG")
vcpkg_list(APPEND arg_OPTIONS -Ddebug=true --prefix "${CURRENT_PACKAGES_DIR}/debug" --includedir ../include)
vcpkg_list(APPEND arg_OPTIONS "--pkg-config-path;['${CURRENT_INSTALLED_DIR}/debug/lib/pkgconfig','${CURRENT_INSTALLED_DIR}/share/pkgconfig']")
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_list(APPEND arg_OPTIONS "-Dcmake_prefix_path=['${CURRENT_INSTALLED_DIR}/debug','${CURRENT_INSTALLED_DIR}','${CURRENT_INSTALLED_DIR}/share']")
else()
vcpkg_list(APPEND arg_OPTIONS "-Dcmake_prefix_path=['${CURRENT_INSTALLED_DIR}/debug','${CURRENT_INSTALLED_DIR}']")
endif()
else()
message(FATAL_ERROR "Unknown configuration. Only DEBUG and RELEASE are valid values.")
endif()
# Allow overrides / additional configuration variables from triplets
if(DEFINED VCPKG_MESON_CONFIGURE_OPTIONS)
vcpkg_list(APPEND arg_OPTIONS ${VCPKG_MESON_CONFIGURE_OPTIONS})
endif()
if(DEFINED VCPKG_MESON_CONFIGURE_OPTIONS_${buildtype})
vcpkg_list(APPEND arg_OPTIONS ${VCPKG_MESON_CONFIGURE_OPTIONS_${buildtype}})
endif()
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
set(MESON_DEFAULT_LIBRARY shared)
else()
set(MESON_DEFAULT_LIBRARY static)
endif()
set(MESON_CMAKE_BUILD_TYPE "${cmake_build_type_${buildtype}}")
z_vcpkg_meson_setup_variables(${buildtype})
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/meson.template.in" "${meson_input_file_${buildtype}}" @ONLY)
set("${arg_OUTPUT}" ${arg_OPTIONS} PARENT_SCOPE)
endfunction()
function(vcpkg_configure_meson)
# parse parameters such that semicolons in options arguments to COMMAND don't get erased
cmake_parse_arguments(PARSE_ARGV 0 arg
"NO_PKG_CONFIG"
"SOURCE_PATH"
"OPTIONS;OPTIONS_DEBUG;OPTIONS_RELEASE;LANGUAGES;ADDITIONAL_BINARIES;ADDITIONAL_NATIVE_BINARIES;ADDITIONAL_CROSS_BINARIES;ADDITIONAL_PROPERTIES"
)
if(DEFINED arg_ADDITIONAL_NATIVE_BINARIES OR DEFINED arg_ADDITIONAL_CROSS_BINARIES)
message(WARNING "Options ADDITIONAL_(NATIVE|CROSS)_BINARIES have been deprecated. Only use ADDITIONAL_BINARIES!")
endif()
vcpkg_list(APPEND arg_ADDITIONAL_BINARIES ${arg_ADDITIONAL_NATIVE_BINARIES} ${arg_ADDITIONAL_CROSS_BINARIES})
vcpkg_list(REMOVE_DUPLICATES arg_ADDITIONAL_BINARIES)
file(REMOVE_RECURSE "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel")
file(REMOVE_RECURSE "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg")
vcpkg_find_acquire_program(MESON)
get_filename_component(CMAKE_PATH "${CMAKE_COMMAND}" DIRECTORY)
vcpkg_add_to_path("${CMAKE_PATH}") # Make CMake invokeable for Meson
vcpkg_find_acquire_program(NINJA)
if(NOT arg_NO_PKG_CONFIG)
vcpkg_find_acquire_program(PKGCONFIG)
set(ENV{PKG_CONFIG} "${PKGCONFIG}")
endif()
vcpkg_find_acquire_program(PYTHON3)
get_filename_component(PYTHON3_DIR "${PYTHON3}" DIRECTORY)
vcpkg_add_to_path(PREPEND "${PYTHON3_DIR}")
set(buildtypes "")
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
set(buildname "DEBUG")
set(cmake_build_type_${buildname} "Debug")
vcpkg_list(APPEND buildtypes "${buildname}")
set(path_suffix_${buildname} "debug/")
set(suffix_${buildname} "dbg")
endif()
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
set(buildname "RELEASE")
set(cmake_build_type_${buildname} "Release")
vcpkg_list(APPEND buildtypes "${buildname}")
set(path_suffix_${buildname} "")
set(suffix_${buildname} "rel")
endif()
# configure build
foreach(buildtype IN LISTS buildtypes)
message(STATUS "Configuring ${TARGET_TRIPLET}-${suffix_${buildtype}}")
file(MAKE_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${suffix_${buildtype}}")
vcpkg_generate_meson_cmd_args(
OUTPUT cmd_args
CONFIG ${buildtype}
LANGUAGES ${arg_LANGUAGES}
OPTIONS ${arg_OPTIONS} ${arg_OPTIONS_${buildtype}}
ADDITIONAL_BINARIES ${arg_ADDITIONAL_BINARIES}
ADDITIONAL_PROPERTIES ${arg_ADDITIONAL_PROPERTIES}
)
vcpkg_execute_required_process(
COMMAND ${MESON} setup ${cmd_args} ${arg_SOURCE_PATH}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${suffix_${buildtype}}"
LOGNAME config-${TARGET_TRIPLET}-${suffix_${buildtype}}
SAVE_LOG_FILES
meson-logs/meson-log.txt
meson-info/intro-dependencies.json
meson-logs/install-log.txt
)
message(STATUS "Configuring ${TARGET_TRIPLET}-${suffix_${buildtype}} done")
endforeach()
endfunction()

View file

@ -0,0 +1,71 @@
function(vcpkg_install_meson)
cmake_parse_arguments(PARSE_ARGV 0 arg "ADD_BIN_TO_PATH" "" "")
vcpkg_find_acquire_program(NINJA)
unset(ENV{DESTDIR}) # installation directory was already specified with '--prefix' option
if(VCPKG_TARGET_IS_OSX)
vcpkg_backup_env_variables(VARS SDKROOT MACOSX_DEPLOYMENT_TARGET)
set(ENV{SDKROOT} "${VCPKG_DETECTED_CMAKE_OSX_SYSROOT}")
set(ENV{MACOSX_DEPLOYMENT_TARGET} "${VCPKG_DETECTED_CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
foreach(buildtype IN ITEMS "debug" "release")
if(DEFINED VCPKG_BUILD_TYPE AND NOT VCPKG_BUILD_TYPE STREQUAL buildtype)
continue()
endif()
if(buildtype STREQUAL "debug")
set(short_buildtype "dbg")
else()
set(short_buildtype "rel")
endif()
message(STATUS "Package ${TARGET_TRIPLET}-${short_buildtype}")
if(arg_ADD_BIN_TO_PATH)
vcpkg_backup_env_variables(VARS PATH)
if(buildtype STREQUAL "debug")
vcpkg_add_to_path(PREPEND "${CURRENT_INSTALLED_DIR}/debug/bin")
else()
vcpkg_add_to_path(PREPEND "${CURRENT_INSTALLED_DIR}/bin")
endif()
endif()
vcpkg_execute_required_process(
COMMAND "${NINJA}" install -v
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${short_buildtype}"
LOGNAME package-${TARGET_TRIPLET}-${short_buildtype}
)
if(arg_ADD_BIN_TO_PATH)
vcpkg_restore_env_variables(VARS PATH)
endif()
endforeach()
vcpkg_list(SET renamed_libs)
if(VCPKG_TARGET_IS_WINDOWS AND VCPKG_LIBRARY_LINKAGE STREQUAL static AND NOT VCPKG_TARGET_IS_MINGW)
# Meson names all static libraries lib<name>.a which basically breaks the world
file(GLOB_RECURSE gen_libraries "${CURRENT_PACKAGES_DIR}*/**/lib*.a")
foreach(gen_library IN LISTS gen_libraries)
get_filename_component(libdir "${gen_library}" DIRECTORY)
get_filename_component(libname "${gen_library}" NAME)
string(REGEX REPLACE ".a$" ".lib" fixed_librawname "${libname}")
string(REGEX REPLACE "^lib" "" fixed_librawname "${fixed_librawname}")
file(RENAME "${gen_library}" "${libdir}/${fixed_librawname}")
# For cmake fixes.
string(REGEX REPLACE ".a$" "" origin_librawname "${libname}")
string(REGEX REPLACE ".lib$" "" fixed_librawname "${fixed_librawname}")
vcpkg_list(APPEND renamed_libs ${fixed_librawname})
set(${librawname}_old ${origin_librawname})
set(${librawname}_new ${fixed_librawname})
endforeach()
file(GLOB_RECURSE cmake_files "${CURRENT_PACKAGES_DIR}*/*.cmake")
foreach(cmake_file IN LISTS cmake_files)
foreach(current_lib IN LISTS renamed_libs)
vcpkg_replace_string("${cmake_file}" "${${current_lib}_old}" "${${current_lib}_new}" IGNORE_UNCHANGED)
endforeach()
endforeach()
endif()
if(VCPKG_TARGET_IS_OSX)
vcpkg_restore_env_variables(VARS SDKROOT MACOSX_DEPLOYMENT_TARGET)
endif()
endfunction()

View file

@ -0,0 +1,8 @@
# See https://github.com/microsoft/vcpkg/discussions/19454
# NOTE: Try to keep in sync with default arm64-osx definition
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_OSX_ARCHITECTURES "arm64;x86_64")

View file

@ -13,9 +13,7 @@
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MSVC-Qt6"
}
"generator": "Ninja"
},
{
"name": "windows_msvc_arm64_cross_base",
@ -23,9 +21,8 @@
"inherits": [
"windows_msvc_base"
],
"architecture": "arm64",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MSVC-arm64-Qt6"
"CMAKE_SYSTEM_NAME": "${hostSystemName}"
}
},
{
@ -34,8 +31,7 @@
"base_debug",
"windows_msvc_base"
],
"displayName": "Windows MSVC (Debug)",
"generator": "Ninja"
"displayName": "Windows MSVC (Debug)"
},
{
"name": "windows_msvc_release",
@ -67,10 +63,7 @@
"base_ci",
"windows_msvc_base"
],
"displayName": "Windows MSVC (CI)",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MSVC-Qt6"
}
"displayName": "Windows MSVC (CI)"
},
{
"name": "windows_msvc_arm64_cross_ci",
@ -78,10 +71,7 @@
"base_ci",
"windows_msvc_arm64_cross_base"
],
"displayName": "Windows MSVC (ARM64 cross, CI)",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MSVC-arm64-Qt6"
}
"displayName": "Windows MSVC (ARM64 cross, CI)"
}
],
"buildPresets": [
@ -110,11 +100,7 @@
],
"displayName": "Windows MSVC (Release)",
"configurePreset": "windows_msvc_release",
"configuration": "Release",
"nativeToolOptions": [
"/p:UseMultiToolTask=true",
"/p:EnforceProcessCountAcrossBuilds=true"
]
"configuration": "Release"
},
{
"name": "windows_msvc_arm64_cross_debug",
@ -123,11 +109,7 @@
],
"displayName": "Windows MSVC (ARM64 cross, Debug)",
"configurePreset": "windows_msvc_arm64_cross_debug",
"configuration": "Debug",
"nativeToolOptions": [
"/p:UseMultiToolTask=true",
"/p:EnforceProcessCountAcrossBuilds=true"
]
"configuration": "Debug"
},
{
"name": "windows_msvc_arm64_cross_release",
@ -136,11 +118,7 @@
],
"displayName": "Windows MSVC (ARM64 cross, Release)",
"configurePreset": "windows_msvc_arm64_cross_release",
"configuration": "Release",
"nativeToolOptions": [
"/p:UseMultiToolTask=true",
"/p:EnforceProcessCountAcrossBuilds=true"
]
"configuration": "Release"
},
{
"name": "windows_msvc_ci",
@ -149,11 +127,7 @@
],
"displayName": "Windows MSVC (CI)",
"configurePreset": "windows_msvc_ci",
"configuration": "Release",
"nativeToolOptions": [
"/p:UseMultiToolTask=true",
"/p:EnforceProcessCountAcrossBuilds=true"
]
"configuration": "Release"
},
{
"name": "windows_msvc_arm64_cross_ci",
@ -162,11 +136,7 @@
],
"displayName": "Windows MSVC (ARM64 cross, CI)",
"configurePreset": "windows_msvc_arm64_cross_ci",
"configuration": "Release",
"nativeToolOptions": [
"/p:UseMultiToolTask=true",
"/p:EnforceProcessCountAcrossBuilds=true"
]
"configuration": "Release"
}
],
"testPresets": [

View file

@ -13,10 +13,7 @@
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"generator": "Ninja",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MinGW-w64-Qt6"
}
"generator": "Ninja"
},
{
"name": "windows_mingw_debug",
@ -40,10 +37,7 @@
"base_ci",
"windows_mingw_base"
],
"displayName": "Windows MinGW (CI)",
"cacheVariables": {
"Launcher_BUILD_ARTIFACT": "Windows-MinGW-w64-Qt6"
}
"displayName": "Windows MinGW (CI)"
}
],
"buildPresets": [

6
flake.lock generated
View file

@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1748460289,
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
"lastModified": 1757745802,
"narHash": "sha256-hLEO2TPj55KcUFUU1vgtHE9UEIOjRcH/4QbmfHNF820=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
"rev": "c23193b943c6c689d70ee98ce3128239ed9e32d1",
"type": "github"
},
"original": {

View file

@ -46,8 +46,6 @@
#include "DataMigrationTask.h"
#include "java/JavaInstallList.h"
#include "net/PasteUpload.h"
#include "pathmatcher/MultiMatcher.h"
#include "pathmatcher/SimplePrefixMatcher.h"
#include "tasks/Task.h"
#include "tools/GenericProfiler.h"
#include "ui/InstanceWindow.h"
@ -864,6 +862,15 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// get rid of invalid meta urls
if (!metaUrl.isValid() || (metaUrl.scheme() != "http" && metaUrl.scheme() != "https"))
m_settings->reset("MetaURLOverride");
// Resource URL
m_settings->registerSetting("ResourceURL", BuildConfig.DEFAULT_RESOURCE_BASE);
QUrl resourceUrl(m_settings->get("ResourceURL").toString());
// get rid of invalid resource urls
if (!resourceUrl.isValid() || (resourceUrl.scheme() != "http" && resourceUrl.scheme() != "https"))
m_settings->reset("ResourceURL");
}
m_settings->registerSetting("CloseAfterLaunch", false);
@ -1482,12 +1489,9 @@ std::shared_ptr<JavaInstallList> Application::javalist()
return m_javalist;
}
QIcon Application::getThemedIcon(const QString& name)
QIcon Application::logo()
{
if (name == "logo") {
return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME);
}
return QIcon::fromTheme(name);
return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME);
}
bool Application::openJsonEditor(const QString& filename)
@ -1976,22 +1980,23 @@ bool Application::handleDataMigration(const QString& currentData,
if (!currentExists) {
// Migrate!
auto matcher = std::make_shared<MultiMatcher>();
matcher->add(std::make_shared<SimplePrefixMatcher>(configFile));
matcher->add(std::make_shared<SimplePrefixMatcher>(
BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before
matcher->add(std::make_shared<SimplePrefixMatcher>("logs/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts.json"));
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("assets/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("icons/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("instances/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("libraries/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("mods/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("themes/"));
using namespace Filters;
QList<Filter> filters;
filters.append(equals(configFile));
filters.append(equals(BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before
filters.append(startsWith("logs/"));
filters.append(equals("accounts.json"));
filters.append(startsWith("accounts/"));
filters.append(startsWith("assets/"));
filters.append(startsWith("icons/"));
filters.append(startsWith("instances/"));
filters.append(startsWith("libraries/"));
filters.append(startsWith("mods/"));
filters.append(startsWith("themes/"));
ProgressDialog diag;
DataMigrationTask task(oldData, currentData, matcher);
DataMigrationTask task(oldData, currentData, any(std::move(filters)));
if (diag.execWithTask(&task)) {
qDebug() << "<> Migration succeeded";
setDoNotMigrate();

View file

@ -116,7 +116,7 @@ class Application : public QApplication {
qint64 timeSinceStart() const { return m_startTime.msecsTo(QDateTime::currentDateTime()); }
QIcon getThemedIcon(const QString& name);
QIcon logo();
ThemeManager* themeManager() { return m_themeManager.get(); }

View file

@ -52,7 +52,6 @@
#include "BaseVersionList.h"
#include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "pathmatcher/IPathMatcher.h"
#include "settings/INIFile.h"
#include "net/Mode.h"

View file

@ -30,21 +30,21 @@ class BaseVersion {
* A string used to identify this version in config files.
* This should be unique within the version list or shenanigans will occur.
*/
virtual QString descriptor() = 0;
virtual QString descriptor() const = 0;
/*!
* The name of this version as it is displayed to the user.
* For example: "1.5.1"
*/
virtual QString name() = 0;
virtual QString name() const = 0;
/*!
* This should return a string that describes
* the kind of version this is (Stable, Beta, Snapshot, whatever)
*/
virtual QString typeString() const = 0;
virtual bool operator<(BaseVersion& a) { return name() < a.name(); }
virtual bool operator>(BaseVersion& a) { return name() > a.name(); }
virtual bool operator<(BaseVersion& a) const { return name() < a.name(); }
virtual bool operator>(BaseVersion& a) const { return name() > a.name(); }
};
Q_DECLARE_METATYPE(BaseVersion::Ptr)

View file

@ -56,7 +56,6 @@ set(CORE_SOURCES
# String filters
Filter.h
Filter.cpp
# JSON parsing helpers
Json.h
@ -108,15 +107,6 @@ if (UNIX AND NOT CYGWIN AND NOT APPLE)
)
endif()
set(PATHMATCHER_SOURCES
# Path matchers
pathmatcher/FSTreeMatcher.h
pathmatcher/IPathMatcher.h
pathmatcher/MultiMatcher.h
pathmatcher/RegexpMatcher.h
pathmatcher/SimplePrefixMatcher.h
)
set(NET_SOURCES
# network stuffs
net/ByteArraySink.h
@ -491,8 +481,11 @@ set(META_SOURCES
set(API_SOURCES
modplatform/ModIndex.h
modplatform/ModIndex.cpp
modplatform/ResourceType.h
modplatform/ResourceType.cpp
modplatform/ResourceAPI.h
modplatform/ResourceAPI.cpp
modplatform/EnsureMetadataTask.h
modplatform/EnsureMetadataTask.cpp
@ -503,8 +496,6 @@ set(API_SOURCES
modplatform/flame/FlameAPI.cpp
modplatform/modrinth/ModrinthAPI.h
modplatform/modrinth/ModrinthAPI.cpp
modplatform/helpers/NetworkResourceAPI.h
modplatform/helpers/NetworkResourceAPI.cpp
modplatform/helpers/HashUtils.h
modplatform/helpers/HashUtils.cpp
modplatform/helpers/OverrideUtils.h
@ -532,8 +523,6 @@ set(FTB_SOURCES
set(FLAME_SOURCES
# Flame
modplatform/flame/FlamePackIndex.cpp
modplatform/flame/FlamePackIndex.h
modplatform/flame/FlameModIndex.cpp
modplatform/flame/FlameModIndex.h
modplatform/flame/PackManifest.h
@ -551,8 +540,6 @@ set(FLAME_SOURCES
set(MODRINTH_SOURCES
modplatform/modrinth/ModrinthPackIndex.cpp
modplatform/modrinth/ModrinthPackIndex.h
modplatform/modrinth/ModrinthPackManifest.cpp
modplatform/modrinth/ModrinthPackManifest.h
modplatform/modrinth/ModrinthCheckUpdate.cpp
modplatform/modrinth/ModrinthCheckUpdate.h
modplatform/modrinth/ModrinthInstanceCreationTask.cpp
@ -755,7 +742,6 @@ endif()
set(LOGIC_SOURCES
${CORE_SOURCES}
${PATHMATCHER_SOURCES}
${NET_SOURCES}
${LAUNCH_SOURCES}
${UPDATE_SOURCES}
@ -1039,8 +1025,6 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/OptionalModDialog.cpp
ui/pages/modplatform/OptionalModDialog.h
ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
ui/pages/modplatform/modrinth/ModrinthResourceModels.h
ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
ui/pages/modplatform/modrinth/ModrinthResourcePages.h
@ -1173,6 +1157,13 @@ SET(LAUNCHER_SOURCES
ui/instanceview/VisualGroup.h
)
if (APPLE)
set(LAUNCHER_SOURCES
${LAUNCHER_SOURCES}
ui/themes/ThemeManager.mm
)
endif()
if (NOT Apple)
set(LAUNCHER_SOURCES
${LAUNCHER_SOURCES}
@ -1303,12 +1294,16 @@ target_link_libraries(Launcher_logic
Launcher_murmur2
nbt++
${ZLIB_LIBRARIES}
tomlplusplus::tomlplusplus
qdcss
BuildConfig
Qt${QT_VERSION_MAJOR}::Widgets
qrcodegenerator
)
if(TARGET PkgConfig::tomlplusplus)
target_link_libraries(Launcher_logic PkgConfig::tomlplusplus)
else()
target_link_libraries(Launcher_logic tomlplusplus::tomlplusplus)
endif()
if (UNIX AND NOT CYGWIN AND NOT APPLE)
target_link_libraries(Launcher_logic
@ -1379,12 +1374,18 @@ if(DEFINED Launcher_APP_BINARY_DEFS)
endif()
install(TARGETS ${Launcher_Name}
RUNTIME_DEPENDENCY_SET LAUNCHER_DEPENDENCY_SET
BUNDLE DESTINATION "." COMPONENT Runtime
LIBRARY DESTINATION ${LIBRARY_DEST_DIR} COMPONENT Runtime
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
)
# Deploy PDBs
if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
install(FILES $<TARGET_PDB_FILE:${Launcher_Name}> DESTINATION ${BINARY_DEST_DIR})
endif()
if(Launcher_BUILD_UPDATER)
# Updater
add_library(prism_updater_logic STATIC ${PRISMUPDATER_SOURCES} ${TASKS_SOURCES} ${PRISMUPDATER_UI})
@ -1418,6 +1419,11 @@ if(Launcher_BUILD_UPDATER)
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
)
# Deploy PDBs
if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
install(FILES $<TARGET_PDB_FILE:${Launcher_Name}_updater> DESTINATION ${BINARY_DEST_DIR})
endif()
endif()
if(WIN32 OR (DEFINED Launcher_BUILD_FILELINKER AND Launcher_BUILD_FILELINKER))
@ -1442,6 +1448,12 @@ if(WIN32 OR (DEFINED Launcher_BUILD_FILELINKER AND Launcher_BUILD_FILELINKER))
add_executable("${Launcher_Name}_filelink" WIN32 filelink/filelink_main.cpp)
target_sources("${Launcher_Name}_filelink" PRIVATE filelink/filelink.exe.manifest)
# HACK: Fix manifest issues with Ninja in release mode (and only release mode) and MSVC
# I have no idea why this works or why it's needed. UPDATE THIS IF YOU EDIT THE MANIFEST!!! -@getchoo
# Thank you 2018 CMake mailing list thread https://cmake.cmake.narkive.com/LnotZXus/conflicting-msvc-manifests
if(MSVC)
set_property(TARGET "${Launcher_Name}_filelink" PROPERTY LINK_FLAGS "/MANIFESTUAC:level='requireAdministrator'")
endif()
target_link_libraries("${Launcher_Name}_filelink" filelink_logic)
@ -1458,6 +1470,11 @@ if(WIN32 OR (DEFINED Launcher_BUILD_FILELINKER AND Launcher_BUILD_FILELINKER))
RUNTIME DESTINATION ${BINARY_DEST_DIR} COMPONENT Runtime
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime
)
# Deploy PDBs
if(WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
install(FILES $<TARGET_PDB_FILE:${Launcher_Name}_filelink> DESTINATION ${BINARY_DEST_DIR})
endif()
endif()
if (UNIX AND APPLE AND Launcher_ENABLE_UPDATER)
@ -1468,186 +1485,64 @@ if (UNIX AND APPLE AND Launcher_ENABLE_UPDATER)
endif()
#### The bundle mess! ####
# Bundle utilities are used to complete the portable packages - they add all the libraries that would otherwise be missing on the target system.
# Bundle utilities are used to complete packages for different platforms - they add all the libraries that would otherwise be missing on the target system.
# NOTE: it seems that this absolutely has to be here, and nowhere else.
if(INSTALL_BUNDLE STREQUAL "full")
if(WIN32 OR (UNIX AND APPLE))
if(WIN32)
set(QT_DEPLOY_TOOL_OPTIONS "--no-opengl-sw --no-quick-import --no-system-d3d-compiler --no-system-dxc-compiler --skip-plugin-types generic,networkinformation")
endif()
qt_generate_deploy_script(
TARGET ${Launcher_Name}
OUTPUT_SCRIPT QT_DEPLOY_SCRIPT
CONTENT "
qt_deploy_runtime_dependencies(
EXECUTABLE ${BINARY_DEST_DIR}/$<TARGET_FILE_NAME:${Launcher_Name}>
BIN_DIR ${BINARY_DEST_DIR}
LIBEXEC_DIR ${LIBRARY_DEST_DIR}
LIB_DIR ${LIBRARY_DEST_DIR}
PLUGINS_DIR ${PLUGIN_DEST_DIR}
NO_OVERWRITE
NO_TRANSLATIONS
NO_COMPILER_RUNTIME
DEPLOY_TOOL_OPTIONS ${QT_DEPLOY_TOOL_OPTIONS}
)"
)
# Bundle our linked dependencies
install(
RUNTIME_DEPENDENCY_SET LAUNCHER_DEPENDENCY_SET
COMPONENT bundle
DIRECTORIES
${CMAKE_SYSTEM_LIBRARY_PATH}
${QT_LIBS_DIR}
${QT_LIBEXECS_DIR}
PRE_EXCLUDE_REGEXES
"^(api-ms-win|ext-ms)-.*\\.dll$"
# FIXME: Why aren't these caught by the below regex???
"^azure.*\\.dll$"
"^vcruntime.*\\.dll$"
POST_EXCLUDE_REGEXES
"system32"
LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
RUNTIME DESTINATION ${BINARY_DEST_DIR}
FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR}
)
# Deploy Qt plugins
install(
SCRIPT ${QT_DEPLOY_SCRIPT}
COMPONENT bundle
)
# Add qt.conf - this makes Qt stop looking for things outside the bundle
install(
CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${RESOURCES_DEST_DIR}/qt.conf\" \" \")"
COMPONENT Runtime
COMPONENT bundle
)
# add qtlogging.ini as a config file
# Add qtlogging.ini as a config file
install(
FILES "qtlogging.ini"
DESTINATION ${CMAKE_INSTALL_PREFIX}/${RESOURCES_DEST_DIR}
COMPONENT Runtime
COMPONENT bundle
)
# Bundle plugins
# Image formats
install(
DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "tga|tiff|mng" EXCLUDE
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "tga|tiff|mng" EXCLUDE
REGEX "d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
# Icon engines
install(
DIRECTORY "${QT_PLUGINS_DIR}/iconengines"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "fontawesome" EXCLUDE
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/iconengines"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "fontawesome" EXCLUDE
REGEX "d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
# Platform plugins
install(
DIRECTORY "${QT_PLUGINS_DIR}/platforms"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "minimal|linuxfb|offscreen" EXCLUDE
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/platforms"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "minimal|linuxfb|offscreen" EXCLUDE
REGEX "[^2]d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
# Style plugins
if(EXISTS "${QT_PLUGINS_DIR}/styles")
install(
DIRECTORY "${QT_PLUGINS_DIR}/styles"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/styles"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "d\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
endif()
# TLS plugins (Qt 6 only)
if(EXISTS "${QT_PLUGINS_DIR}/tls")
install(
DIRECTORY "${QT_PLUGINS_DIR}/tls"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
PATTERN "*qcertonlybackend*" EXCLUDE
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/tls"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "dd\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
PATTERN "*qcertonlybackend*" EXCLUDE
)
endif()
# Wayland support
if(EXISTS "${QT_PLUGINS_DIR}/wayland-graphics-integration-client")
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-graphics-integration-client"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-graphics-integration-client"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "dd\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
endif()
if(EXISTS "${QT_PLUGINS_DIR}/wayland-graphics-integration-server")
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-graphics-integration-server"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-graphics-integration-server"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "dd\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
endif()
if(EXISTS "${QT_PLUGINS_DIR}/wayland-decoration-client")
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-decoration-client"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-decoration-client"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "dd\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
endif()
if(EXISTS "${QT_PLUGINS_DIR}/wayland-shell-integration")
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-shell-integration"
CONFIGURATIONS Debug RelWithDebInfo ""
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
)
install(
DIRECTORY "${QT_PLUGINS_DIR}/wayland-shell-integration"
CONFIGURATIONS Release MinSizeRel
DESTINATION ${PLUGIN_DEST_DIR}
COMPONENT Runtime
REGEX "dd\\." EXCLUDE
REGEX "_debug\\." EXCLUDE
REGEX "\\.dSYM" EXCLUDE
)
endif()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/install_prereqs.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/install_prereqs.cmake"
@ONLY
)
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/install_prereqs.cmake" COMPONENT Runtime)
endif()

View file

@ -12,7 +12,7 @@
#include <QtConcurrent>
DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathMatcher)
DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathMatcher)
: Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
{
m_copy.matcher(m_pathMatcher).whitelist(true);

View file

@ -5,7 +5,7 @@
#pragma once
#include "FileSystem.h"
#include "pathmatcher/IPathMatcher.h"
#include "Filter.h"
#include "tasks/Task.h"
#include <QFuture>
@ -18,7 +18,7 @@
class DataMigrationTask : public Task {
Q_OBJECT
public:
explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher);
explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathmatcher);
~DataMigrationTask() override = default;
protected:
@ -33,7 +33,7 @@ class DataMigrationTask : public Task {
private:
const QString& m_sourcePath;
const QString& m_targetPath;
const IPathMatcher::Ptr m_pathMatcher;
const Filter m_pathMatcher;
FS::copy m_copy;
int m_toCopy = 0;

View file

@ -331,7 +331,7 @@ bool copy::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual copying
auto copy_file = [this, dryRun, src, dst, opt, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist))
if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return;
auto dst_path = PathCombine(dst, relative_dst_path);
@ -418,7 +418,7 @@ void create_link::make_link_list(const QString& offset)
// Function that'll do the actual linking
auto link_file = [this, dst](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) {
if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist)) {
qDebug() << "path" << relative_dst_path << "in black list or not in whitelist";
return;
}
@ -897,6 +897,29 @@ QString getApplicationsDir()
return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
}
QString quoteArgs(const QStringList& args, const QString& wrap, const QString& escapeChar, bool wrapOnlyIfNeeded = false)
{
QString result;
auto size = args.size();
for (int i = 0; i < size; ++i) {
QString arg = args[i];
arg.replace(wrap, escapeChar);
bool needsWrapping = !wrapOnlyIfNeeded || arg.contains(' ') || arg.contains('\t') || arg.contains(wrap);
if (needsWrapping)
result += wrap + arg + wrap;
else
result += arg;
if (i < size - 1)
result += ' ';
}
return result;
}
// Cross-platform Shortcut creation
QString createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
{
@ -940,9 +963,7 @@ QString createShortcut(QString destination, QString target, QStringList args, QS
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f);
QString argstring;
if (!args.empty())
argstring = " \"" + args.join("\" \"") + "\"";
auto argstring = quoteArgs(args, "\"", "\\\"");
stream << "#!/bin/bash" << "\n";
stream << "\"" << target << "\" " << argstring << "\n";
@ -984,14 +1005,12 @@ QString createShortcut(QString destination, QString target, QStringList args, QS
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f);
QString argstring;
if (!args.empty())
argstring = " '" + args.join("' '") + "'";
auto argstring = quoteArgs(args, "'", "'\\''");
stream << "[Desktop Entry]" << "\n";
stream << "Type=Application" << "\n";
stream << "Categories=Game;ActionGame;AdventureGame;Simulation" << "\n";
stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n";
stream << "Exec=\"" << target.toLocal8Bit() << "\" " << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
if (!icon.isEmpty()) {
stream << "Icon=" << icon.toLocal8Bit() << "\n";
@ -1030,20 +1049,7 @@ QString createShortcut(QString destination, QString target, QStringList args, QS
return QString();
}
QString argStr;
int argCount = args.count();
for (int i = 0; i < argCount; i++) {
if (args[i].contains(' ')) {
argStr.append('"').append(args[i]).append('"');
} else {
argStr.append(args[i]);
}
if (i < argCount - 1) {
argStr.append(" ");
}
}
auto argStr = quoteArgs(args, "\"", "\\\"", true);
if (argStr.length() >= MAX_PATH) {
qWarning() << "Arguments string is too long!";
return QString();
@ -1271,7 +1277,7 @@ bool clone::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual cloneing
auto cloneFile = [this, dryRun, dst, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist))
if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return;
auto dst_path = PathCombine(dst, relative_dst_path);

View file

@ -38,7 +38,7 @@
#pragma once
#include "Exception.h"
#include "pathmatcher/IPathMatcher.h"
#include "Filter.h"
#include <system_error>
@ -115,9 +115,9 @@ class copy : public QObject {
m_followSymlinks = follow;
return *this;
}
copy& matcher(IPathMatcher::Ptr filter)
copy& matcher(Filter filter)
{
m_matcher = filter;
m_matcher = std::move(filter);
return *this;
}
copy& whitelist(bool whitelist)
@ -147,7 +147,7 @@ class copy : public QObject {
private:
bool m_followSymlinks = true;
IPathMatcher::Ptr m_matcher = nullptr;
Filter m_matcher = nullptr;
bool m_whitelist = false;
bool m_overwrite = false;
QDir m_src;
@ -209,9 +209,9 @@ class create_link : public QObject {
m_useHardLinks = useHard;
return *this;
}
create_link& matcher(IPathMatcher::Ptr filter)
create_link& matcher(Filter filter)
{
m_matcher = filter;
m_matcher = std::move(filter);
return *this;
}
create_link& whitelist(bool whitelist)
@ -260,7 +260,7 @@ class create_link : public QObject {
private:
bool m_useHardLinks = false;
IPathMatcher::Ptr m_matcher = nullptr;
Filter m_matcher = nullptr;
bool m_whitelist = false;
bool m_recursive = true;
@ -492,9 +492,9 @@ class clone : public QObject {
m_src.setPath(src);
m_dst.setPath(dst);
}
clone& matcher(IPathMatcher::Ptr filter)
clone& matcher(Filter filter)
{
m_matcher = filter;
m_matcher = std::move(filter);
return *this;
}
clone& whitelist(bool whitelist)
@ -518,7 +518,7 @@ class clone : public QObject {
bool operator()(const QString& offset, bool dryRun = false);
private:
IPathMatcher::Ptr m_matcher = nullptr;
Filter m_matcher = nullptr;
bool m_whitelist = false;
QDir m_src;
QDir m_dst;

View file

@ -1,37 +0,0 @@
#include "Filter.h"
ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern) {}
bool ContainsFilter::accepts(const QString& value)
{
return value.contains(pattern);
}
ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern) {}
bool ExactFilter::accepts(const QString& value)
{
return value == pattern;
}
ExactIfPresentFilter::ExactIfPresentFilter(const QString& pattern) : pattern(pattern) {}
bool ExactIfPresentFilter::accepts(const QString& value)
{
return value.isEmpty() || value == pattern;
}
RegexpFilter::RegexpFilter(const QString& regexp, bool invert) : invert(invert)
{
pattern.setPattern(regexp);
pattern.optimize();
}
bool RegexpFilter::accepts(const QString& value)
{
auto match = pattern.match(value);
bool matched = match.hasMatch();
return invert ? (!matched) : (matched);
}
ExactListFilter::ExactListFilter(const QStringList& pattern) : m_pattern(pattern) {}
bool ExactListFilter::accepts(const QString& value)
{
return m_pattern.isEmpty() || m_pattern.contains(value);
}

View file

@ -3,59 +3,52 @@
#include <QRegularExpression>
#include <QString>
class Filter {
public:
virtual ~Filter() = default;
virtual bool accepts(const QString& value) = 0;
};
using Filter = std::function<bool(const QString&)>;
class ContainsFilter : public Filter {
public:
ContainsFilter(const QString& pattern);
virtual ~ContainsFilter() = default;
bool accepts(const QString& value) override;
namespace Filters {
inline Filter inverse(Filter filter)
{
return [filter = std::move(filter)](const QString& src) { return !filter(src); };
}
private:
QString pattern;
};
inline Filter any(QList<Filter> filters)
{
return [filters = std::move(filters)](const QString& src) {
for (auto& filter : filters)
if (filter(src))
return true;
class ExactFilter : public Filter {
public:
ExactFilter(const QString& pattern);
virtual ~ExactFilter() = default;
bool accepts(const QString& value) override;
return false;
};
}
private:
QString pattern;
};
inline Filter equals(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src == pattern; };
}
class ExactIfPresentFilter : public Filter {
public:
ExactIfPresentFilter(const QString& pattern);
virtual ~ExactIfPresentFilter() override = default;
bool accepts(const QString& value) override;
inline Filter equalsAny(QStringList patterns = {})
{
return [patterns = std::move(patterns)](const QString& src) { return patterns.isEmpty() || patterns.contains(src); };
}
private:
QString pattern;
};
inline Filter equalsOrEmpty(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src.isEmpty() || src == pattern; };
}
class RegexpFilter : public Filter {
public:
RegexpFilter(const QString& regexp, bool invert);
virtual ~RegexpFilter() = default;
bool accepts(const QString& value) override;
inline Filter contains(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src.contains(pattern); };
}
private:
QRegularExpression pattern;
bool invert = false;
};
inline Filter startsWith(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src.startsWith(pattern); };
}
class ExactListFilter : public Filter {
public:
ExactListFilter(const QStringList& pattern = {});
virtual ~ExactListFilter() = default;
bool accepts(const QString& value) override;
private:
QStringList m_pattern;
};
inline Filter regexp(QRegularExpression pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return pattern.match(src).hasMatch(); };
}
} // namespace Filters

View file

@ -8,23 +8,23 @@
struct InstanceCopyPrefs {
public:
[[nodiscard]] bool allTrue() const;
[[nodiscard]] QString getSelectedFiltersAsRegex() const;
[[nodiscard]] QString getSelectedFiltersAsRegex(const QStringList& additionalFilters) const;
bool allTrue() const;
QString getSelectedFiltersAsRegex() const;
QString getSelectedFiltersAsRegex(const QStringList& additionalFilters) const;
// Getters
[[nodiscard]] bool isCopySavesEnabled() const;
[[nodiscard]] bool isKeepPlaytimeEnabled() const;
[[nodiscard]] bool isCopyGameOptionsEnabled() const;
[[nodiscard]] bool isCopyResourcePacksEnabled() const;
[[nodiscard]] bool isCopyShaderPacksEnabled() const;
[[nodiscard]] bool isCopyServersEnabled() const;
[[nodiscard]] bool isCopyModsEnabled() const;
[[nodiscard]] bool isCopyScreenshotsEnabled() const;
[[nodiscard]] bool isUseSymLinksEnabled() const;
[[nodiscard]] bool isLinkRecursivelyEnabled() const;
[[nodiscard]] bool isUseHardLinksEnabled() const;
[[nodiscard]] bool isDontLinkSavesEnabled() const;
[[nodiscard]] bool isUseCloneEnabled() const;
bool isCopySavesEnabled() const;
bool isKeepPlaytimeEnabled() const;
bool isCopyGameOptionsEnabled() const;
bool isCopyResourcePacksEnabled() const;
bool isCopyShaderPacksEnabled() const;
bool isCopyServersEnabled() const;
bool isCopyModsEnabled() const;
bool isCopyScreenshotsEnabled() const;
bool isUseSymLinksEnabled() const;
bool isLinkRecursivelyEnabled() const;
bool isUseHardLinksEnabled() const;
bool isDontLinkSavesEnabled() const;
bool isUseCloneEnabled() const;
// Setters
void enableCopySaves(bool b);
void enableKeepPlaytime(bool b);

View file

@ -3,8 +3,8 @@
#include <QtConcurrentRun>
#include <memory>
#include "FileSystem.h"
#include "Filter.h"
#include "NullInstance.h"
#include "pathmatcher/RegexpMatcher.h"
#include "settings/INISettingsObject.h"
#include "tasks/Task.h"
@ -30,9 +30,8 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP
if (!filters.isEmpty()) {
// Set regex filter:
// FIXME: get this from the original instance type...
auto matcherReal = new RegexpMatcher(filters);
matcherReal->caseSensitive(false);
m_matcher.reset(matcherReal);
QRegularExpression regexp(filters, QRegularExpression::CaseInsensitiveOption);
m_matcher = Filters::regexp(regexp);
}
}

View file

@ -5,6 +5,7 @@
#include <QUrl>
#include "BaseInstance.h"
#include "BaseVersion.h"
#include "Filter.h"
#include "InstanceCopyPrefs.h"
#include "InstanceTask.h"
#include "net/NetJob.h"
@ -28,7 +29,7 @@ class InstanceCopyTask : public InstanceTask {
InstancePtr m_origInstance;
QFuture<bool> m_copyFuture;
QFutureWatcher<bool> m_copyFutureWatcher;
IPathMatcher::Ptr m_matcher;
Filter m_matcher;
bool m_keepPlaytime;
bool m_useLinks = false;
bool m_useHardLinks = false;

View file

@ -263,9 +263,9 @@ void InstanceImportTask::extractFinished()
}
}
bool installIcon(QString root, QString instIcon)
bool installIcon(QString root, QString instIconKey)
{
auto importIconPath = IconUtils::findBestIconIn(root, instIcon);
auto importIconPath = IconUtils::findBestIconIn(root, instIconKey);
if (importIconPath.isNull() || !QFile::exists(importIconPath))
importIconPath = IconUtils::findBestIconIn(root, "icon.png");
if (importIconPath.isNull() || !QFile::exists(importIconPath))
@ -273,10 +273,10 @@ bool installIcon(QString root, QString instIcon)
if (!importIconPath.isNull() && QFile::exists(importIconPath)) {
// import icon
auto iconList = APPLICATION->icons();
if (iconList->iconFileExists(instIcon)) {
iconList->deleteIcon(instIcon);
if (iconList->iconFileExists(instIconKey)) {
iconList->deleteIcon(instIconKey);
}
iconList->installIcon(importIconPath, instIcon);
iconList->installIcon(importIconPath, instIconKey + ".png");
return true;
}
return false;

View file

@ -45,7 +45,7 @@ class InstancePageProvider : protected QObject, public BasePageProvider {
values.append(new ServersPage(onesix));
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix));
values.append(new OtherLogsPage("logs", tr("Other logs"), "Other-Logs", inst));
values.append(new OtherLogsPage("logs", tr("Other Logs"), "Other-Logs", inst));
return values;
}

View file

@ -14,10 +14,10 @@ struct InstanceName {
InstanceName() = default;
InstanceName(QString name, QString version) : m_original_name(std::move(name)), m_original_version(std::move(version)) {}
[[nodiscard]] QString modifiedName() const;
[[nodiscard]] QString originalName() const;
[[nodiscard]] QString name() const;
[[nodiscard]] QString version() const;
QString modifiedName() const;
QString originalName() const;
QString name() const;
QString version() const;
void setName(QString name) { m_modified_name = name; }
void setName(InstanceName& other);
@ -44,12 +44,12 @@ class InstanceTask : public Task, public InstanceName {
void setGroup(const QString& group) { m_instGroup = group; }
QString group() const { return m_instGroup; }
[[nodiscard]] bool shouldConfirmUpdate() const { return m_confirm_update; }
bool shouldConfirmUpdate() const { return m_confirm_update; }
void setConfirmUpdate(bool confirm) { m_confirm_update = confirm; }
bool shouldOverride() const { return m_override_existing; }
[[nodiscard]] QString originalInstanceID() const { return m_original_instance_id; };
QString originalInstanceID() const { return m_original_instance_id; };
protected:
void setOverride(bool override, QString instance_id_to_override = {})

View file

@ -200,7 +200,7 @@ void LaunchController::login()
if ((m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) ||
m_accountToUse->shouldRefresh()) {
// Force account refresh on the account used to launch the instance updating the AccountState
// only on first try and if it is not meant to be offline
// only on first try and if it is not meant to be offline
m_accountToUse->refresh();
}
while (tryagain) {
@ -296,11 +296,15 @@ void LaunchController::login()
case AccountState::Working: {
// refresh is in progress, we need to wait for it to finish to proceed.
ProgressDialog progDialog(m_parentWidget);
if (m_online) {
progDialog.setSkipButton(true, tr("Play Offline"));
}
progDialog.setSkipButton(true, tr("Abort"));
auto task = accountToCheck->currentTask();
progDialog.execWithTask(task.get());
// don't retry if aborted
if (task->getState() == Task::State::AbortedByUser)
tryagain = false;
continue;
}
case AccountState::Expired: {

View file

@ -51,7 +51,7 @@
namespace MMCZip {
// ours
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const FilterFunction& filter)
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const Filter& filter)
{
QuaZip modZip(from.filePath());
modZip.open(QuaZip::mdUnzip);

View file

@ -52,16 +52,16 @@
#if defined(LAUNCHER_APPLICATION)
#include "minecraft/mod/Mod.h"
#endif
#include "Filter.h"
#include "tasks/Task.h"
namespace MMCZip {
using FilterFunction = std::function<bool(const QString&)>;
using FilterFileFunction = std::function<bool(const QFileInfo&)>;
/**
* Merge two zip files, using a filter function
*/
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const FilterFunction& filter = nullptr);
bool mergeZipFiles(QuaZip* into, QFileInfo from, QSet<QString>& contained, const Filter& filter = nullptr);
/**
* Compress directory, by providing a list of files to compress

View file

@ -1,7 +1,7 @@
#pragma once
#include <qlogging.h>
#include <QString>
#include <QtLogging>
/**
* @brief the MessageLevel Enum

View file

@ -78,7 +78,7 @@ QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory)
}
for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) {
auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
if (m_matcher->matches(relPath)) {
if (m_matcher(relPath)) {
ret.append(relPath);
}
}

View file

@ -2,7 +2,7 @@
#include <QDir>
#include <QFileSystemWatcher>
#include "pathmatcher/IPathMatcher.h"
#include "Filter.h"
class RecursiveFileSystemWatcher : public QObject {
Q_OBJECT
@ -16,7 +16,7 @@ class RecursiveFileSystemWatcher : public QObject {
void setWatchFiles(bool watchFiles);
bool watchFiles() const { return m_watchFiles; }
void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; }
void setMatcher(Filter matcher) { m_matcher = std::move(matcher); }
QStringList files() const { return m_files; }
@ -32,7 +32,7 @@ class RecursiveFileSystemWatcher : public QObject {
QDir m_root;
bool m_watchFiles = false;
bool m_isEnabled = false;
IPathMatcher::Ptr m_matcher;
Filter m_matcher;
QFileSystemWatcher* m_watcher;

View file

@ -96,8 +96,8 @@ class Version {
QString m_fullString;
[[nodiscard]] inline bool isAppendix() const { return m_stringPart.startsWith('+'); }
[[nodiscard]] inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; }
inline bool isAppendix() const { return m_stringPart.startsWith('+'); }
inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; }
inline bool operator==(const Section& other) const
{

View file

@ -37,9 +37,9 @@
#include "VersionProxyModel.h"
#include <Version.h>
#include <meta/VersionList.h>
#include <QIcon>
#include <QPixmapCache>
#include <QSortFilterProxyModel>
#include "Application.h"
class VersionFilterModel : public QSortFilterProxyModel {
Q_OBJECT
@ -63,7 +63,7 @@ class VersionFilterModel : public QSortFilterProxyModel {
for (auto it = filters.begin(); it != filters.end(); ++it) {
auto data = sourceModel()->data(idx, it.key());
auto match = data.toString();
if (!it.value()->accepts(match)) {
if (!it.value()(match)) {
return false;
}
}
@ -206,11 +206,11 @@ QVariant VersionProxyModel::data(const QModelIndex& index, int role) const
if (column == Name && hasRecommended) {
auto recommenced = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
if (recommenced.toBool()) {
return APPLICATION->getThemedIcon("star");
return QIcon::fromTheme("star");
} else if (hasLatest) {
auto latest = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
if (latest.toBool()) {
return APPLICATION->getThemedIcon("bug");
return QIcon::fromTheme("bug");
}
}
QPixmap pixmap;
@ -380,9 +380,9 @@ void VersionProxyModel::clearFilters()
filterModel->filterChanged();
}
void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter* f)
void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter f)
{
m_filters[column].reset(f);
m_filters[column] = std::move(f);
filterModel->filterChanged();
}

View file

@ -10,7 +10,7 @@ class VersionProxyModel : public QAbstractProxyModel {
Q_OBJECT
public:
enum Column { Name, ParentVersion, Branch, Type, CPUArchitecture, Path, Time, JavaName, JavaMajor };
using FilterMap = QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>>;
using FilterMap = QHash<BaseVersionList::ModelRoles, Filter>;
public:
VersionProxyModel(QObject* parent = 0);
@ -28,7 +28,7 @@ class VersionProxyModel : public QAbstractProxyModel {
const FilterMap& filters() const;
const QString& search() const;
void setFilter(BaseVersionList::ModelRoles column, Filter* filter);
void setFilter(BaseVersionList::ModelRoles column, Filter filter);
void setSearch(const QString& search);
void clearFilters();
QModelIndex getRecommended() const;

View file

@ -55,7 +55,7 @@ IconList::IconList(const QStringList& builtinPaths, const QString& path, QObject
QDir instanceIcons(builtinPath);
auto fileInfoList = instanceIcons.entryInfoList(QDir::Files, QDir::Name);
for (const auto& fileInfo : fileInfoList) {
builtinNames.insert(fileInfo.baseName());
builtinNames.insert(fileInfo.completeBaseName());
}
}
for (const auto& builtinName : builtinNames) {
@ -127,10 +127,11 @@ QStringList IconList::getIconFilePaths() const
QString formatName(const QDir& iconsDir, const QFileInfo& iconFile)
{
if (iconFile.dir() == iconsDir)
return iconFile.baseName();
return iconFile.completeBaseName();
constexpr auto delimiter = " » ";
QString relativePathWithoutExtension = iconsDir.relativeFilePath(iconFile.dir().path()) + QDir::separator() + iconFile.baseName();
QString relativePathWithoutExtension =
iconsDir.relativeFilePath(iconFile.dir().path()) + QDir::separator() + iconFile.completeBaseName();
return relativePathWithoutExtension.replace(QDir::separator(), delimiter);
}

View file

@ -1,26 +0,0 @@
set(CMAKE_MODULE_PATH "@CMAKE_MODULE_PATH@")
file(GLOB_RECURSE QTPLUGINS "${CMAKE_INSTALL_PREFIX}/@PLUGIN_DEST_DIR@/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
function(gp_resolved_file_type_override resolved_file type_var)
if(resolved_file MATCHES "^/(usr/)?lib/libQt")
set(${type_var} other PARENT_SCOPE)
elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libxcb-")
set(${type_var} other PARENT_SCOPE)
elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libicu")
set(${type_var} other PARENT_SCOPE)
elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libpng")
set(${type_var} other PARENT_SCOPE)
elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libproxy")
set(${type_var} other PARENT_SCOPE)
elseif((resolved_file MATCHES "^/(usr/)?lib(.+)?/libstdc\\+\\+") AND (UNIX AND NOT APPLE))
set(${type_var} other PARENT_SCOPE)
endif()
endfunction()
set(gp_tool "@CMAKE_GP_TOOL@")
set(gp_cmd_paths ${gp_cmd_paths}
"@CMAKE_GP_CMD_PATHS@"
)
include(BundleUtilities)
fixup_bundle("@APPS@" "${QTPLUGINS}" "@DIRS@")

View file

@ -21,7 +21,7 @@
#include "BaseVersion.h"
#include "StringUtils.h"
bool JavaInstall::operator<(const JavaInstall& rhs)
bool JavaInstall::operator<(const JavaInstall& rhs) const
{
auto archCompare = StringUtils::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive);
if (archCompare != 0)
@ -35,17 +35,17 @@ bool JavaInstall::operator<(const JavaInstall& rhs)
return StringUtils::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0;
}
bool JavaInstall::operator==(const JavaInstall& rhs)
bool JavaInstall::operator==(const JavaInstall& rhs) const
{
return arch == rhs.arch && id == rhs.id && path == rhs.path;
}
bool JavaInstall::operator>(const JavaInstall& rhs)
bool JavaInstall::operator>(const JavaInstall& rhs) const
{
return (!operator<(rhs)) && (!operator==(rhs));
}
bool JavaInstall::operator<(BaseVersion& a)
bool JavaInstall::operator<(BaseVersion& a) const
{
try {
return operator<(dynamic_cast<JavaInstall&>(a));
@ -54,7 +54,7 @@ bool JavaInstall::operator<(BaseVersion& a)
}
}
bool JavaInstall::operator>(BaseVersion& a)
bool JavaInstall::operator>(BaseVersion& a) const
{
try {
return operator>(dynamic_cast<JavaInstall&>(a));

View file

@ -24,17 +24,17 @@
struct JavaInstall : public BaseVersion {
JavaInstall() {}
JavaInstall(QString id, QString arch, QString path) : id(id), arch(arch), path(path) {}
virtual QString descriptor() override { return id.toString(); }
virtual QString descriptor() const override { return id.toString(); }
virtual QString name() override { return id.toString(); }
virtual QString name() const override { return id.toString(); }
virtual QString typeString() const override { return arch; }
virtual bool operator<(BaseVersion& a) override;
virtual bool operator>(BaseVersion& a) override;
bool operator<(const JavaInstall& rhs);
bool operator==(const JavaInstall& rhs);
bool operator>(const JavaInstall& rhs);
virtual bool operator<(BaseVersion& a) const override;
virtual bool operator>(BaseVersion& a) const override;
bool operator<(const JavaInstall& rhs) const;
bool operator==(const JavaInstall& rhs) const;
bool operator>(const JavaInstall& rhs) const;
JavaVersion id;
QString arch;

View file

@ -35,7 +35,7 @@ class JavaInstallList : public BaseVersionList {
public:
explicit JavaInstallList(QObject* parent = 0, bool onlyManagedVersions = false);
[[nodiscard]] Task::Ptr getLoadTask() override;
Task::Ptr getLoadTask() override;
bool isLoaded() override;
const BaseVersion::Ptr at(int i) const override;
int count() const override;

View file

@ -78,7 +78,7 @@ MetadataPtr parseJavaMeta(const QJsonObject& in)
return meta;
}
bool Metadata::operator<(const Metadata& rhs)
bool Metadata::operator<(const Metadata& rhs) const
{
auto id = version;
if (id < rhs.version) {
@ -97,17 +97,17 @@ bool Metadata::operator<(const Metadata& rhs)
return StringUtils::naturalCompare(m_name, rhs.m_name, Qt::CaseInsensitive) < 0;
}
bool Metadata::operator==(const Metadata& rhs)
bool Metadata::operator==(const Metadata& rhs) const
{
return version == rhs.version && m_name == rhs.m_name;
}
bool Metadata::operator>(const Metadata& rhs)
bool Metadata::operator>(const Metadata& rhs) const
{
return (!operator<(rhs)) && (!operator==(rhs));
}
bool Metadata::operator<(BaseVersion& a)
bool Metadata::operator<(BaseVersion& a) const
{
try {
return operator<(dynamic_cast<Metadata&>(a));
@ -116,7 +116,7 @@ bool Metadata::operator<(BaseVersion& a)
}
}
bool Metadata::operator>(BaseVersion& a)
bool Metadata::operator>(BaseVersion& a) const
{
try {
return operator>(dynamic_cast<Metadata&>(a));

View file

@ -32,17 +32,17 @@ enum class DownloadType { Manifest, Archive, Unknown };
class Metadata : public BaseVersion {
public:
virtual QString descriptor() override { return version.toString(); }
virtual QString descriptor() const override { return version.toString(); }
virtual QString name() override { return m_name; }
virtual QString name() const override { return m_name; }
virtual QString typeString() const override { return vendor; }
virtual bool operator<(BaseVersion& a) override;
virtual bool operator>(BaseVersion& a) override;
bool operator<(const Metadata& rhs);
bool operator==(const Metadata& rhs);
bool operator>(const Metadata& rhs);
virtual bool operator<(BaseVersion& a) const override;
virtual bool operator>(BaseVersion& a) const override;
bool operator<(const Metadata& rhs) const;
bool operator==(const Metadata& rhs) const;
bool operator>(const Metadata& rhs) const;
QString m_name;
QString vendor;

View file

@ -63,7 +63,7 @@ bool JavaVersion::isModular() const
return m_parseable && m_major >= 9;
}
bool JavaVersion::operator<(const JavaVersion& rhs)
bool JavaVersion::operator<(const JavaVersion& rhs) const
{
if (m_parseable && rhs.m_parseable) {
auto major = m_major;
@ -101,7 +101,7 @@ bool JavaVersion::operator<(const JavaVersion& rhs)
return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0;
}
bool JavaVersion::operator==(const JavaVersion& rhs)
bool JavaVersion::operator==(const JavaVersion& rhs) const
{
if (m_parseable && rhs.m_parseable) {
return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease;
@ -109,7 +109,7 @@ bool JavaVersion::operator==(const JavaVersion& rhs)
return m_string == rhs.m_string;
}
bool JavaVersion::operator>(const JavaVersion& rhs)
bool JavaVersion::operator>(const JavaVersion& rhs) const
{
return (!operator<(rhs)) && (!operator==(rhs));
}

View file

@ -20,9 +20,9 @@ class JavaVersion {
JavaVersion& operator=(const QString& rhs);
bool operator<(const JavaVersion& rhs);
bool operator==(const JavaVersion& rhs);
bool operator>(const JavaVersion& rhs);
bool operator<(const JavaVersion& rhs) const;
bool operator==(const JavaVersion& rhs) const;
bool operator>(const JavaVersion& rhs) const;
bool requiresPermGen() const;
bool defaultsToUtf8() const;

View file

@ -28,7 +28,7 @@ class ArchiveDownloadTask : public Task {
ArchiveDownloadTask(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = "");
virtual ~ArchiveDownloadTask() = default;
[[nodiscard]] bool canAbort() const override { return true; }
bool canAbort() const override { return true; }
void executeTask() override;
virtual bool abort() override;

View file

@ -29,7 +29,7 @@ class ManifestDownloadTask : public Task {
ManifestDownloadTask(QUrl url, QString final_path, QString checksumType = "", QString checksumHash = "");
virtual ~ManifestDownloadTask() = default;
[[nodiscard]] bool canAbort() const override { return true; }
bool canAbort() const override { return true; }
void executeTask() override;
virtual bool abort() override;

View file

@ -21,11 +21,11 @@
Meta::Version::Version(const QString& uid, const QString& version) : BaseVersion(), m_uid(uid), m_version(version) {}
QString Meta::Version::descriptor()
QString Meta::Version::descriptor() const
{
return m_version;
}
QString Meta::Version::name()
QString Meta::Version::name() const
{
if (m_data)
return m_data->name;
@ -88,7 +88,7 @@ QString Meta::Version::localFilename() const
::Version Meta::Version::toComparableVersion() const
{
return { const_cast<Meta::Version*>(this)->descriptor() };
return { descriptor() };
}
void Meta::Version::setType(const QString& type)

View file

@ -40,8 +40,8 @@ class Version : public QObject, public BaseVersion, public BaseEntity {
explicit Version(const QString& uid, const QString& version);
virtual ~Version() = default;
QString descriptor() override;
QString name() override;
QString descriptor() const override;
QString name() const override;
QString typeString() const override;
QString uid() const { return m_uid; }
@ -60,7 +60,7 @@ class Version : public QObject, public BaseVersion, public BaseEntity {
QString localFilename() const override;
[[nodiscard]] ::Version toComparableVersion() const;
::Version toComparableVersion() const;
public: // for usage by format parsers only
void setType(const QString& type);

View file

@ -37,7 +37,7 @@ class VersionList : public BaseVersionList, public BaseEntity {
enum Roles { UidRole = Qt::UserRole + 100, TimeRole, RequiresRole, VersionPtrRole };
bool isLoaded() override;
[[nodiscard]] Task::Ptr getLoadTask() override;
Task::Ptr getLoadTask() override;
const BaseVersion::Ptr at(int i) const override;
int count() const override;
void sortVersions() override;

View file

@ -298,7 +298,8 @@ QString AssetObject::getLocalPath()
QUrl AssetObject::getUrl()
{
return BuildConfig.RESOURCE_BASE + getRelPath();
auto resourceURL = APPLICATION->settings()->get("ResourceURL").toString();
return resourceURL + getRelPath();
}
QString AssetObject::getRelPath()

View file

@ -748,7 +748,6 @@ void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg)
d->remoteLoadSuccessful = false;
taskSlot.succeeded = false;
taskSlot.finished = true;
taskSlot.error = msg;
d->remoteTasksInProgress--;
checkIfAllFinished();
}
@ -769,7 +768,9 @@ void ComponentUpdateTask::checkIfAllFinished()
QStringList allErrorsList;
for (auto& item : d->remoteLoadStatusList) {
if (!item.succeeded) {
allErrorsList.append(item.error);
const ComponentPtr component = d->m_profile->getComponent(item.PackProfileIndex);
allErrorsList.append(tr("Could not download metadata for %1 %2. Please change the version or try again later.")
.arg(component->getName(), component->m_version));
}
}
auto allErrors = allErrorsList.join("\n");

View file

@ -15,7 +15,6 @@ struct RemoteLoadStatus {
size_t PackProfileIndex = 0;
bool finished = false;
bool succeeded = false;
QString error;
Task::Ptr task;
};

View file

@ -242,13 +242,13 @@ bool Library::isActive(const RuntimeContext& runtimeContext) const
if (m_rules.empty()) {
result = true;
} else {
RuleAction ruleResult = Disallow;
Rule::Action ruleResult = Rule::Disallow;
for (auto rule : m_rules) {
RuleAction temp = rule->apply(this, runtimeContext);
if (temp != Defer)
Rule::Action temp = rule.apply(runtimeContext);
if (temp != Rule::Defer)
ruleResult = temp;
}
result = result && (ruleResult == Allow);
result = result && (ruleResult == Rule::Allow);
}
if (isNative()) {
result = result && !getCompatibleNative(runtimeContext).isNull();

View file

@ -129,7 +129,7 @@ class Library {
void setHint(const QString& hint) { m_hint = hint; }
/// Set the load rules
void setRules(QList<std::shared_ptr<Rule>> rules) { m_rules = rules; }
void setRules(QList<Rule> rules) { m_rules = rules; }
/// Returns true if the library should be loaded (or extracted, in case of natives)
bool isActive(const RuntimeContext& runtimeContext) const;
@ -203,7 +203,7 @@ class Library {
bool applyRules = false;
/// rules associated with the library
QList<std::shared_ptr<Rule>> m_rules;
QList<Rule> m_rules;
/// MOJANG: container with Mojang style download info
MojangLibraryDownloadInfo::Ptr m_mojangDownloads;

View file

@ -53,7 +53,6 @@
#include "FileSystem.h"
#include "MMCTime.h"
#include "java/JavaVersion.h"
#include "pathmatcher/MultiMatcher.h"
#include "launch/LaunchTask.h"
#include "launch/TaskStepWrapper.h"

View file

@ -103,7 +103,7 @@ class MinecraftInstance : public BaseInstance {
QString getLocalLibraryPath() const;
/** Returns whether the instance, with its version, has support for demo mode. */
[[nodiscard]] bool supportsDemo() const;
bool supportsDemo() const;
void updateRuntimeContext() override;

View file

@ -319,7 +319,11 @@ LibraryPtr MojangVersionFormat::libraryFromJson(ProblemContainer& problems, cons
}
if (libObj.contains("rules")) {
out->applyRules = true;
out->m_rules = rulesFromJsonV4(libObj);
QJsonArray rulesArray = requireArray(libObj.value("rules"));
for (auto rule : rulesArray) {
out->m_rules.append(Rule::fromJson(requireObject(rule)));
}
}
if (libObj.contains("downloads")) {
out->m_mojangDownloads = libDownloadInfoFromJson(libObj);
@ -355,7 +359,7 @@ QJsonObject MojangVersionFormat::libraryToJson(Library* library)
if (!library->m_rules.isEmpty()) {
QJsonArray allRules;
for (auto& rule : library->m_rules) {
QJsonObject ruleObj = rule->toJson();
QJsonObject ruleObj = rule.toJson();
allRules.append(ruleObj);
}
libRoot.insert("rules", allRules);

View file

@ -2,6 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2025 TheKodeToad <TheKodeToad@proton.me>
*
* 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
@ -38,72 +39,54 @@
#include "Rule.h"
RuleAction RuleAction_fromString(QString name)
Rule Rule::fromJson(const QJsonObject& object)
{
if (name == "allow")
return Allow;
if (name == "disallow")
return Disallow;
return Defer;
}
Rule result;
QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject& objectWithRules)
{
QList<std::shared_ptr<Rule>> rules;
auto rulesVal = objectWithRules.value("rules");
if (!rulesVal.isArray())
return rules;
if (object["action"] == "allow")
result.m_action = Allow;
else if (object["action"] == "disallow")
result.m_action = Disallow;
QJsonArray ruleList = rulesVal.toArray();
for (auto ruleVal : ruleList) {
std::shared_ptr<Rule> rule;
if (!ruleVal.isObject())
continue;
auto ruleObj = ruleVal.toObject();
auto actionVal = ruleObj.value("action");
if (!actionVal.isString())
continue;
auto action = RuleAction_fromString(actionVal.toString());
if (action == Defer)
continue;
auto osVal = ruleObj.value("os");
if (!osVal.isObject()) {
// add a new implicit action rule
rules.append(ImplicitRule::create(action));
continue;
}
auto osObj = osVal.toObject();
auto osNameVal = osObj.value("name");
if (!osNameVal.isString())
continue;
QString osName = osNameVal.toString();
QString versionRegex = osObj.value("version").toString();
// add a new OS rule
rules.append(OsRule::create(action, osName, versionRegex));
}
return rules;
}
QJsonObject ImplicitRule::toJson()
{
QJsonObject ruleObj;
ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
return ruleObj;
}
QJsonObject OsRule::toJson()
{
QJsonObject ruleObj;
ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
QJsonObject osObj;
{
osObj.insert("name", m_system);
if (!m_version_regexp.isEmpty()) {
osObj.insert("version", m_version_regexp);
if (auto os = object["os"]; os.isObject()) {
if (auto name = os["name"].toString(); !name.isNull()) {
result.m_os = OS{
name,
os["version"].toString(),
};
}
}
ruleObj.insert("os", osObj);
return ruleObj;
return result;
}
QJsonObject Rule::toJson()
{
QJsonObject result;
if (m_action == Allow)
result["action"] = "allow";
else if (m_action == Disallow)
result["action"] = "disallow";
if (m_os.has_value()) {
QJsonObject os;
os["name"] = m_os->name;
if (!m_os->version.isEmpty())
os["version"] = m_os->version;
result["os"] = os;
}
return result;
}
Rule::Action Rule::apply(const RuntimeContext& runtimeContext)
{
if (m_os.has_value() && !runtimeContext.classifierMatches(m_os->name))
return Defer;
return m_action;
}

View file

@ -2,6 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2025 TheKodeToad <TheKodeToad@proton.me>
*
* 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
@ -38,59 +39,27 @@
#include <QJsonObject>
#include <QList>
#include <QString>
#include <memory>
#include "RuntimeContext.h"
class Library;
class Rule;
enum RuleAction { Allow, Disallow, Defer };
QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject& objectWithRules);
class Rule {
protected:
RuleAction m_result;
virtual bool applies(const Library* parent, const RuntimeContext& runtimeContext) = 0;
public:
Rule(RuleAction result) : m_result(result) {}
virtual ~Rule() {}
virtual QJsonObject toJson() = 0;
RuleAction apply(const Library* parent, const RuntimeContext& runtimeContext)
{
if (applies(parent, runtimeContext))
return m_result;
else
return Defer;
}
};
enum Action { Allow, Disallow, Defer };
static Rule fromJson(const QJsonObject& json);
QJsonObject toJson();
Action apply(const RuntimeContext& runtimeContext);
class OsRule : public Rule {
private:
// the OS
QString m_system;
// the OS version regexp
QString m_version_regexp;
struct OS {
QString name;
// FIXME: unsupported
// retained to avoid information being lost from files
QString version;
};
protected:
virtual bool applies(const Library*, const RuntimeContext& runtimeContext) { return runtimeContext.classifierMatches(m_system); }
OsRule(RuleAction result, QString system, QString version_regexp) : Rule(result), m_system(system), m_version_regexp(version_regexp) {}
public:
virtual QJsonObject toJson();
static std::shared_ptr<OsRule> create(RuleAction result, QString system, QString version_regexp)
{
return std::shared_ptr<OsRule>(new OsRule(result, system, version_regexp));
}
};
class ImplicitRule : public Rule {
protected:
virtual bool applies(const Library*, [[maybe_unused]] const RuntimeContext& runtimeContext) { return true; }
ImplicitRule(RuleAction result) : Rule(result) {}
public:
virtual QJsonObject toJson();
static std::shared_ptr<ImplicitRule> create(RuleAction result) { return std::shared_ptr<ImplicitRule>(new ImplicitRule(result)); }
Action m_action = Defer;
std::optional<OS> m_os;
};

View file

@ -123,7 +123,7 @@ bool createInstanceShortcut(const Shortcut& shortcut, const QString& filePath)
// part of fix for weird bug involving the window icon being replaced
// dunno why it happens, but parent 2-line fix seems to be enough, so w/e
auto appIcon = APPLICATION->getThemedIcon("logo");
auto appIcon = APPLICATION->logo();
QFile iconFile(iconPath);
if (!iconFile.open(QFile::WriteOnly)) {

View file

@ -59,7 +59,7 @@ class World {
// WEAK compare operator - used for replacing worlds
bool operator==(const World& other) const;
[[nodiscard]] auto isSymLink() const -> bool { return m_containerFile.isSymLink(); }
auto isSymLink() const -> bool { return m_containerFile.isSymLink(); }
/**
* @brief Take a instance path, checks if the file pointed to by the resource is a symlink or under a symlink in that instance
@ -68,9 +68,9 @@ class World {
* @return true
* @return false
*/
[[nodiscard]] bool isSymLinkUnder(const QString& instPath) const;
bool isSymLinkUnder(const QString& instPath) const;
[[nodiscard]] bool isMoreThanOneHardLink() const;
bool isMoreThanOneHardLink() const;
QString canonicalFilePath() const { return m_containerFile.canonicalFilePath(); }

View file

@ -36,6 +36,7 @@
#include "WorldList.h"
#include <FileSystem.h>
#include <qmimedata.h>
#include <QDebug>
#include <QDirIterator>
#include <QFileSystemWatcher>
@ -301,50 +302,31 @@ QStringList WorldList::mimeTypes() const
return types;
}
class WorldMimeData : public QMimeData {
Q_OBJECT
public:
WorldMimeData(QList<World> worlds) { m_worlds = worlds; }
QStringList formats() const { return QMimeData::formats() << "text/uri-list"; }
protected:
QVariant retrieveData(const QString& mimetype, QMetaType type) const
{
QList<QUrl> urls;
for (auto& world : m_worlds) {
if (!world.isValid() || !world.isOnFS())
continue;
QString worldPath = world.container().absoluteFilePath();
qDebug() << worldPath;
urls.append(QUrl::fromLocalFile(worldPath));
}
const_cast<WorldMimeData*>(this)->setUrls(urls);
return QMimeData::retrieveData(mimetype, type);
}
private:
QList<World> m_worlds;
};
QMimeData* WorldList::mimeData(const QModelIndexList& indexes) const
{
if (indexes.size() == 0)
return new QMimeData();
QList<QUrl> urls;
QList<World> worlds_;
for (auto idx : indexes) {
if (idx.column() != 0)
continue;
int row = idx.row();
if (row < 0 || row >= this->m_worlds.size())
continue;
worlds_.append(this->m_worlds[row]);
const World& world = m_worlds[row];
if (!world.isValid() || !world.isOnFS())
continue;
QString worldPath = world.container().absoluteFilePath();
qDebug() << worldPath;
urls.append(QUrl::fromLocalFile(worldPath));
}
if (!worlds_.size()) {
return new QMimeData();
}
return new WorldMimeData(worlds_);
auto result = new QMimeData();
result->setUrls(urls);
return result;
}
Qt::ItemFlags WorldList::flags(const QModelIndex& index) const
@ -453,5 +435,3 @@ void WorldList::loadWorldsAsync()
});
}
}
#include "WorldList.moc"

View file

@ -180,6 +180,7 @@ MinecraftProfile profileFromJSONV3(const QJsonObject& parent, const char* tokenN
}
out.skin.id = idV.toString();
out.skin.url = urlV.toString();
out.skin.url.replace("http://textures.minecraft.net", "https://textures.minecraft.net");
out.skin.variant = variantV.toString();
// data for skin is optional
@ -216,6 +217,7 @@ MinecraftProfile profileFromJSONV3(const QJsonObject& parent, const char* tokenN
Cape cape;
cape.id = idV.toString();
cape.url = urlV.toString();
cape.url.replace("http://textures.minecraft.net", "https://textures.minecraft.net");
cape.alias = aliasV.toString();
// data for cape is optional.

View file

@ -181,8 +181,10 @@ void MinecraftAccount::authFailed(QString reason)
data.validity_ = Validity::None;
emit changed();
} break;
case AccountTaskState::STATE_WORKING: {
data.accountState = AccountState::Unchecked;
} break;
case AccountTaskState::STATE_CREATED:
case AccountTaskState::STATE_WORKING:
case AccountTaskState::STATE_SUCCEEDED: {
// Not reachable here, as they are not failures.
}

View file

@ -114,7 +114,7 @@ class MinecraftAccount : public QObject, public Usable {
bool isActive() const;
[[nodiscard]] AccountType accountType() const noexcept { return data.type; }
AccountType accountType() const noexcept { return data.type; }
bool ownsMinecraft() const { return data.type != AccountType::Offline && data.minecraftEntitlement.ownsMinecraft; }

View file

@ -207,6 +207,7 @@ bool parseMinecraftProfile(QByteArray& data, MinecraftProfile& output)
if (!getString(capeObj.value("url"), capeOut.url)) {
continue;
}
capeOut.url.replace("http://textures.minecraft.net", "https://textures.minecraft.net");
if (!getString(capeObj.value("alias"), capeOut.alias)) {
continue;
}
@ -358,6 +359,7 @@ bool parseMinecraftProfileMojang(QByteArray& data, MinecraftProfile& output)
qWarning() << "Skin url is not a string";
return false;
}
skinOut.url.replace("http://textures.minecraft.net", "https://textures.minecraft.net");
auto maybeMeta = skin.find("metadata");
if (maybeMeta != skin.end() && maybeMeta->isObject()) {
@ -371,6 +373,7 @@ bool parseMinecraftProfileMojang(QByteArray& data, MinecraftProfile& output)
qWarning() << "Cape url is not a string";
return false;
}
capeOut.url.replace("http://textures.minecraft.net", "https://textures.minecraft.net");
// we don't know the cape ID as it is not returned from the session server
// so just fake it - changing capes is probably locked anyway :(

View file

@ -40,15 +40,15 @@ class DataPack : public Resource {
DataPack(QFileInfo file_info) : Resource(file_info) {}
/** Gets the numerical ID of the pack format. */
[[nodiscard]] int packFormat() const { return m_pack_format; }
int packFormat() const { return m_pack_format; }
/** Gets, respectively, the lower and upper versions supported by the set pack format. */
[[nodiscard]] virtual std::pair<Version, Version> compatibleVersions() const;
virtual std::pair<Version, Version> compatibleVersions() const;
/** Gets the description of the data pack. */
[[nodiscard]] QString description() const { return m_description; }
QString description() const { return m_description; }
/** Gets the image of the data pack, converted to a QPixmap for drawing, and scaled to size. */
[[nodiscard]] QPixmap image(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const;
QPixmap image(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const;
/** Thread-safe. */
void setPackFormat(int new_format_id);
@ -64,8 +64,6 @@ class DataPack : public Resource {
[[nodiscard]] int compare(Resource const& other, SortType type) const override;
[[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
virtual QString directory() { return "/data"; }
protected:
mutable QMutex m_data_lock;

View file

@ -42,7 +42,6 @@
#include <QIcon>
#include <QStyle>
#include "Application.h"
#include "Version.h"
#include "minecraft/mod/tasks/LocalDataPackParseTask.h"
@ -92,7 +91,7 @@ QVariant DataPackFolderModel::data(const QModelIndex& index, int role) const
}
case Qt::DecorationRole: {
if (column == NameColumn && (at(row).isSymLinkUnder(instDirPath()) || at(row).isMoreThanOneHardLink()))
return APPLICATION->getThemedIcon("status-yellow");
return QIcon::fromTheme("status-yellow");
if (column == ImageColumn) {
return at(row).image({ 32, 32 }, Qt::AspectRatioMode::KeepAspectRatioByExpanding);
}

View file

@ -50,10 +50,10 @@ class DataPackFolderModel : public ResourceFolderModel {
virtual QString id() const override { return "datapacks"; }
[[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
[[nodiscard]] int columnCount(const QModelIndex& parent) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int columnCount(const QModelIndex& parent) const override;
[[nodiscard]] Resource* createResource(const QFileInfo& file) override;
[[nodiscard]] Task* createParseTask(Resource&) override;

View file

@ -19,27 +19,16 @@
#pragma once
#include <memory>
#include "modplatform/packwiz/Packwiz.h"
// launcher/minecraft/mod/Mod.h
class Mod;
namespace Metadata {
using ModStruct = Packwiz::V1::Mod;
using ModSide = Packwiz::V1::Side;
inline auto create(const QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> ModStruct
inline ModStruct create(const QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version)
{
return Packwiz::V1::createModFormat(index_dir, mod_pack, mod_version);
}
inline auto create(const QDir& index_dir, Mod& internal_mod, QString mod_slug) -> ModStruct
{
return Packwiz::V1::createModFormat(index_dir, internal_mod, std::move(mod_slug));
}
inline void update(const QDir& index_dir, ModStruct& mod)
{
Packwiz::V1::updateModIndex(index_dir, mod);
@ -50,24 +39,14 @@ inline void remove(const QDir& index_dir, QString mod_slug)
Packwiz::V1::deleteModIndex(index_dir, mod_slug);
}
inline void remove(const QDir& index_dir, QVariant& mod_id)
{
Packwiz::V1::deleteModIndex(index_dir, mod_id);
}
inline auto get(const QDir& index_dir, QString mod_slug) -> ModStruct
inline ModStruct get(const QDir& index_dir, QString mod_slug)
{
return Packwiz::V1::getIndexForMod(index_dir, std::move(mod_slug));
}
inline auto get(const QDir& index_dir, QVariant& mod_id) -> ModStruct
inline ModStruct get(const QDir& index_dir, QVariant& mod_id)
{
return Packwiz::V1::getIndexForMod(index_dir, mod_id);
}
inline auto modSideToString(ModSide side) -> QString
{
return Packwiz::V1::sideToString(side);
}
}; // namespace Metadata

Some files were not shown because too many files have changed in this diff Show more