mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-04-29 22:24:26 +02:00
Merge remote-tracking branch 'upstream/develop' into shallow-lazy-otherlogs
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
commit
1e3c197222
103
.github/actions/get-merge-commit/action.yml
vendored
Normal file
103
.github/actions/get-merge-commit/action.yml
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
# This file incorporates work covered by the following copyright and
|
||||
# permission notice
|
||||
#
|
||||
# Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors
|
||||
#
|
||||
# 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.
|
||||
|
||||
name: Get merge commit
|
||||
description: Get a merge commit of a given pull request
|
||||
|
||||
inputs:
|
||||
repository:
|
||||
description: Repository containing the pull request
|
||||
required: false
|
||||
pull-request-id:
|
||||
description: ID of a pull request
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
merge-commit-sha:
|
||||
description: Git SHA of a merge commit
|
||||
value: ${{ steps.query.outputs.merge-commit-sha }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Wait for GitHub to report merge commit
|
||||
id: query
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_REPO: ${{ inputs.repository || github.repository }}
|
||||
PR_ID: ${{ inputs.pull-request-id }}
|
||||
# https://github.com/NixOS/nixpkgs/blob/8f77f3600f1ee775b85dc2c72fd842768e486ec9/ci/get-merge-commit.sh
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
log() {
|
||||
echo "$@" >&2
|
||||
}
|
||||
|
||||
# Retry the API query this many times
|
||||
retryCount=5
|
||||
# Start with 5 seconds, but double every retry
|
||||
retryInterval=5
|
||||
|
||||
while true; do
|
||||
log "Checking whether the pull request can be merged"
|
||||
prInfo=$(gh api \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"/repos/$GITHUB_REPO/pulls/$PR_ID")
|
||||
|
||||
# Non-open PRs won't have their mergeability computed no matter what
|
||||
state=$(jq -r .state <<<"$prInfo")
|
||||
if [[ "$state" != open ]]; then
|
||||
log "PR is not open anymore"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mergeable=$(jq -r .mergeable <<<"$prInfo")
|
||||
if [[ "$mergeable" == "null" ]]; then
|
||||
if ((retryCount == 0)); then
|
||||
log "Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com/"
|
||||
exit 3
|
||||
else
|
||||
((retryCount -= 1)) || true
|
||||
|
||||
# null indicates that GitHub is still computing whether it's mergeable
|
||||
# Wait a couple seconds before trying again
|
||||
log "GitHub is still computing whether this PR can be merged, waiting $retryInterval seconds before trying again ($retryCount retries left)"
|
||||
sleep "$retryInterval"
|
||||
|
||||
((retryInterval *= 2)) || true
|
||||
fi
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$mergeable" == "true" ]]; then
|
||||
echo "merge-commit-sha=$(jq -r .merge_commit_sha <<<"$prInfo")" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "# 🚨 The PR has a merge conflict!" >>> "$GITHUB_STEP_SUMMARY"
|
||||
exit 2
|
||||
fi
|
28
.github/workflows/build.yml
vendored
28
.github/workflows/build.yml
vendored
@ -52,13 +52,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
qt_ver: 5
|
||||
qt_host: linux
|
||||
qt_arch: ""
|
||||
qt_version: "5.15.2"
|
||||
qt_modules: "qtnetworkauth"
|
||||
|
||||
- os: ubuntu-22.04
|
||||
qt_ver: 6
|
||||
qt_host: linux
|
||||
@ -254,7 +247,7 @@ jobs:
|
||||
arch: ${{ matrix.vcvars_arch }}
|
||||
|
||||
- name: Prepare AppImage (Linux)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||
if: runner.os == 'Linux'
|
||||
env:
|
||||
APPIMAGEUPDATE_HASH: ${{ matrix.appimageupdate_hash }}
|
||||
LINUXDEPLOY_HASH: ${{ matrix.linuxdeploy_hash }}
|
||||
@ -287,7 +280,7 @@ jobs:
|
||||
##
|
||||
|
||||
- name: Configure CMake (macOS)
|
||||
if: runner.os == 'macOS' && matrix.qt_ver == 6
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_ENABLE_JAVA_DOWNLOADER=ON -DLauncher_BUILD_PLATFORM=official -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja
|
||||
|
||||
@ -502,7 +495,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Package AppImage (Linux)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
@ -598,29 +591,22 @@ jobs:
|
||||
name: PrismLauncher-${{ matrix.name }}-Setup-${{ env.VERSION }}-${{ inputs.build_type }}
|
||||
path: PrismLauncher-Setup.exe
|
||||
|
||||
- name: Upload binary tarball (Linux, portable, Qt 5)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 6
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PrismLauncher-${{ runner.os }}-Qt5-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
|
||||
path: PrismLauncher-portable.tar.gz
|
||||
|
||||
- name: Upload binary tarball (Linux, portable, Qt 6)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||
- name: Upload binary tarball (Linux, portable)
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PrismLauncher-${{ runner.os }}-Qt6-Portable-${{ env.VERSION }}-${{ inputs.build_type }}
|
||||
path: PrismLauncher-portable.tar.gz
|
||||
|
||||
- name: Upload AppImage (Linux)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
|
||||
path: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage
|
||||
|
||||
- name: Upload AppImage Zsync (Linux)
|
||||
if: runner.os == 'Linux' && matrix.qt_ver != 5
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PrismLauncher-${{ runner.os }}-${{ env.VERSION }}-${{ inputs.build_type }}-x86_64.AppImage.zsync
|
||||
|
56
.github/workflows/codeql.yml
vendored
56
.github/workflows/codeql.yml
vendored
@ -1,6 +1,39 @@
|
||||
name: "CodeQL Code Scanning"
|
||||
|
||||
on: [ push, pull_request, workflow_dispatch ]
|
||||
on:
|
||||
push:
|
||||
# NOTE: `!` doesn't work with `paths-ignore` :(
|
||||
# So we a catch-all glob instead
|
||||
# https://github.com/orgs/community/discussions/25369#discussioncomment-3247674
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/codeql.yml"
|
||||
- "!flatpak/"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
pull_request:
|
||||
# See above
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/codeql.yml"
|
||||
- "!flatpak/"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
CodeQL:
|
||||
@ -10,7 +43,7 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
submodules: "true"
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
@ -20,14 +53,25 @@ jobs:
|
||||
languages: cpp, java
|
||||
|
||||
- name: Install Dependencies
|
||||
run:
|
||||
sudo apt-get -y update
|
||||
run: sudo apt-get -y update
|
||||
|
||||
sudo apt-get -y install ninja-build extra-cmake-modules scdoc qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5core5a libqt5network5 libqt5gui5 libqt5networkauth5 libqt5networkauth5-dev libqt5opengl5 libqt5opengl5-dev
|
||||
sudo apt-get -y install ninja-build extra-cmake-modules scdoc
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
aqtversion: "==3.1.*"
|
||||
py7zrversion: ">=0.20.2"
|
||||
version: "6.8.1"
|
||||
host: "linux"
|
||||
target: "desktop"
|
||||
arch: ""
|
||||
modules: "qt5compat qtimageformats qtnetworkauth"
|
||||
tools: ""
|
||||
|
||||
- name: Configure and Build
|
||||
run: |
|
||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DLauncher_QT_VERSION_MAJOR=5 -G Ninja
|
||||
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -G Ninja
|
||||
|
||||
cmake --build build
|
||||
|
||||
|
40
.github/workflows/flatpak.yml
vendored
40
.github/workflows/flatpak.yml
vendored
@ -2,22 +2,38 @@ name: Flatpak
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**/LICENSE"
|
||||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".markdownlint**"
|
||||
- "nix/**"
|
||||
# We don't do anything with these artifacts on releases. They go to Flathub
|
||||
tags-ignore:
|
||||
- "*"
|
||||
# NOTE: `!` doesn't work with `paths-ignore` :(
|
||||
# So we a catch-all glob instead
|
||||
# https://github.com/orgs/community/discussions/25369#discussioncomment-3247674
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/flatpak.yml"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**/LICENSE"
|
||||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".markdownlint**"
|
||||
- "nix/**"
|
||||
# See above
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/flatpak.yml"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
|
14
.github/workflows/merge-blocking-pr.yml
vendored
14
.github/workflows/merge-blocking-pr.yml
vendored
@ -1,9 +1,15 @@
|
||||
name: Merged Blocking Pull Request Automation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_id:
|
||||
description: Local Pull Request number to work on
|
||||
required: true
|
||||
type: number
|
||||
|
||||
jobs:
|
||||
update-blocked-status:
|
||||
@ -12,7 +18,7 @@ jobs:
|
||||
|
||||
# a pr that was a `blocking:<id>` label was merged.
|
||||
# find the open pr's it was blocked by and trigger a refresh of their state
|
||||
if: github.event.pull_request.merged == true && contains( join( github.event.pull_request.labels.*.name, ',' ), 'blocking' )
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'blocking') }}
|
||||
|
||||
steps:
|
||||
- name: Generate token
|
||||
@ -26,11 +32,11 @@ jobs:
|
||||
id: gather_deps
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_NUMBER: ${{ inputs.pr_id || github.event.pull_request.number }}
|
||||
run: |
|
||||
blocked_prs=$(
|
||||
gh -R ${{ github.repository }} pr list --label 'blocked' --json 'number,body' \
|
||||
| jq -c --argjson pr "${{ github.event.pull_request.number }}" '
|
||||
| jq -c --argjson pr "$PR_NUMBER" '
|
||||
reduce ( .[] | select(
|
||||
.body |
|
||||
scan("(?:blocked (?:by|on)|stacked on):? #([0-9]+)") |
|
||||
|
55
.github/workflows/nix.yml
vendored
55
.github/workflows/nix.yml
vendored
@ -4,28 +4,34 @@ on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
paths-ignore:
|
||||
- ".github/**"
|
||||
- "!.github/workflows/nix.yml"
|
||||
- "flatpak/"
|
||||
- "scripts/"
|
||||
# NOTE: `!` doesn't work with `paths-ignore` :(
|
||||
# So we a catch-all glob instead
|
||||
# https://github.com/orgs/community/discussions/25369#discussioncomment-3247674
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/nix.yml"
|
||||
- "!flatpak/"
|
||||
- "!scripts/"
|
||||
|
||||
- ".git*"
|
||||
- ".envrc"
|
||||
- "**.md"
|
||||
- "!COPYING.md"
|
||||
- "renovate.json"
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
pull_request_target:
|
||||
paths-ignore:
|
||||
- ".github/**"
|
||||
- "flatpak/"
|
||||
- "scripts/"
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/nix.yml"
|
||||
- "!flatpak/"
|
||||
- "!scripts/"
|
||||
|
||||
- ".git*"
|
||||
- ".envrc"
|
||||
- "**.md"
|
||||
- "!COPYING.md"
|
||||
- "renovate.json"
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@ -61,11 +67,20 @@ jobs:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Get merge commit
|
||||
if: ${{ github.event_name == 'pull_request_target' }}
|
||||
id: merge-commit
|
||||
uses: PrismLauncher/PrismLauncher/.github/actions/get-merge-commit@develop
|
||||
with:
|
||||
pull-request-id: ${{ github.event.pull_request.id }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ steps.merge-commit.outputs.merge-commit-sha || github.sha }}
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@v16
|
||||
uses: DeterminateSystems/nix-installer-action@v17
|
||||
with:
|
||||
determinate: ${{ env.USE_DETERMINATE }}
|
||||
|
||||
|
46
.github/workflows/trigger_builds.yml
vendored
46
.github/workflows/trigger_builds.yml
vendored
@ -4,21 +4,39 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- "renovate/**"
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**/LICENSE"
|
||||
- "flake.lock"
|
||||
- "packages/**"
|
||||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".markdownlint**"
|
||||
# NOTE: `!` doesn't work with `paths-ignore` :(
|
||||
# So we a catch-all glob instead
|
||||
# https://github.com/orgs/community/discussions/25369#discussioncomment-3247674
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/build.yml"
|
||||
- ".github/workflows/trigger_builds.yml"
|
||||
- "!flatpak/"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**/LICENSE"
|
||||
- "flake.lock"
|
||||
- "packages/**"
|
||||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".markdownlint**"
|
||||
# See above
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/**"
|
||||
- ".github/workflows/build.yml"
|
||||
- ".github/workflows/trigger_builds.yml"
|
||||
- "!flatpak/"
|
||||
- "!nix/"
|
||||
- "!scripts/"
|
||||
|
||||
- "!.git*"
|
||||
- "!.envrc"
|
||||
- "!**.md"
|
||||
- "COPYING.md"
|
||||
- "!renovate.json"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
2
.github/workflows/trigger_release.yml
vendored
2
.github/workflows/trigger_release.yml
vendored
@ -46,7 +46,6 @@ 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-Linux-Qt5-Portable*/PrismLauncher-portable.tar.gz PrismLauncher-Linux-Qt5-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-macOS*/PrismLauncher.zip PrismLauncher-macOS-${{ env.VERSION }}.zip
|
||||
@ -89,7 +88,6 @@ jobs:
|
||||
draft: true
|
||||
prerelease: false
|
||||
files: |
|
||||
PrismLauncher-Linux-Qt5-Portable-${{ env.VERSION }}.tar.gz
|
||||
PrismLauncher-Linux-x86_64.AppImage
|
||||
PrismLauncher-Linux-x86_64.AppImage.zsync
|
||||
PrismLauncher-Linux-Qt6-Portable-${{ env.VERSION }}.tar.gz
|
||||
|
2
.github/workflows/update-flake.yml
vendored
2
.github/workflows/update-flake.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@d1ca217b388ee87b2507a9a93bf01368bde7cec2 # v31
|
||||
- uses: cachix/install-nix-action@754537aaedb35f72ab11a60cc162c49ef3016495 # v31
|
||||
|
||||
- uses: DeterminateSystems/update-flake-lock@v24
|
||||
with:
|
||||
|
@ -88,10 +88,8 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Fix build with Qt 5.13
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_DISABLE_DEPRECATED_BEFORE=0x050C00")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_WARN_DEPRECATED_UP_TO=0x060200")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_DISABLE_DEPRECATED_UP_TO=0x060000")
|
||||
|
||||
# Fix aarch64 build for toml++
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0")
|
||||
@ -310,23 +308,7 @@ endif()
|
||||
|
||||
# Find the required Qt parts
|
||||
include(QtVersionlessBackport)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 5)
|
||||
set(QT_VERSION_MAJOR 5)
|
||||
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml NetworkAuth OpenGL)
|
||||
find_package(Qt5 COMPONENTS DBus)
|
||||
list(APPEND Launcher_QT_DBUS Qt5::DBus)
|
||||
|
||||
if(NOT Launcher_FORCE_BUNDLED_LIBS)
|
||||
find_package(QuaZip-Qt5 1.3 QUIET)
|
||||
endif()
|
||||
if (NOT QuaZip-Qt5_FOUND)
|
||||
set(QUAZIP_QT_MAJOR_VERSION ${QT_VERSION_MAJOR} CACHE STRING "Qt version to use (4, 5 or 6), defaults to ${QT_VERSION_MAJOR}" FORCE)
|
||||
set(FORCE_BUNDLED_QUAZIP 1)
|
||||
endif()
|
||||
|
||||
# Qt 6 sets these by default. Notably causes Windows APIs to use UNICODE strings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE -D_UNICODE")
|
||||
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
set(QT_VERSION_MAJOR 6)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core CoreTools Widgets Concurrent Network Test Xml Core5Compat NetworkAuth OpenGL)
|
||||
find_package(Qt6 COMPONENTS DBus)
|
||||
@ -344,22 +326,12 @@ else()
|
||||
message(FATAL_ERROR "Qt version ${Launcher_QT_VERSION_MAJOR} is not supported")
|
||||
endif()
|
||||
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 5)
|
||||
include(ECMQueryQt)
|
||||
ecm_query_qt(QT_PLUGINS_DIR QT_INSTALL_PLUGINS)
|
||||
ecm_query_qt(QT_LIBS_DIR QT_INSTALL_LIBS)
|
||||
ecm_query_qt(QT_LIBEXECS_DIR QT_INSTALL_LIBEXECS)
|
||||
else()
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
set(QT_PLUGINS_DIR ${QT${QT_VERSION_MAJOR}_INSTALL_PREFIX}/${QT${QT_VERSION_MAJOR}_INSTALL_PLUGINS})
|
||||
set(QT_LIBS_DIR ${QT${QT_VERSION_MAJOR}_INSTALL_PREFIX}/${QT${QT_VERSION_MAJOR}_INSTALL_LIBS})
|
||||
set(QT_LIBEXECS_DIR ${QT${QT_VERSION_MAJOR}_INSTALL_PREFIX}/${QT${QT_VERSION_MAJOR}_INSTALL_LIBEXECS})
|
||||
endif()
|
||||
|
||||
# NOTE: Qt 6 already sets this by default
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
if(NOT Launcher_FORCE_BUNDLED_LIBS)
|
||||
# Find toml++
|
||||
find_package(tomlplusplus 3.2.0 QUIET)
|
||||
|
@ -108,7 +108,7 @@
|
||||
|
||||
Information on third party licenses used in MinGW-w64 can be found in its COPYING.MinGW-w64-runtime.txt.
|
||||
|
||||
## Qt 5/6
|
||||
## Qt 6
|
||||
|
||||
Copyright (C) 2022 The Qt Company Ltd and other contributors.
|
||||
Contact: https://www.qt.io/licensing
|
||||
|
18
flake.lock
generated
18
flake.lock
generated
@ -3,11 +3,11 @@
|
||||
"libnbtplusplus": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1699286814,
|
||||
"narHash": "sha256-yy0q+bky80LtK1GWzz7qpM+aAGrOqLuewbid8WT1ilk=",
|
||||
"lastModified": 1744811532,
|
||||
"narHash": "sha256-qhmjaRkt+O7A+gu6HjUkl7QzOEb4r8y8vWZMG2R/C6o=",
|
||||
"owner": "PrismLauncher",
|
||||
"repo": "libnbtplusplus",
|
||||
"rev": "23b955121b8217c1c348a9ed2483167a6f3ff4ad",
|
||||
"rev": "531449ba1c930c98e0bcf5d332b237a8566f9d78",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -18,11 +18,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1744463964,
|
||||
"narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=",
|
||||
"lastModified": 1744932701,
|
||||
"narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
|
||||
"rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -35,11 +35,11 @@
|
||||
"qt-qrcodegenerator": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1731907326,
|
||||
"narHash": "sha256-5+iYwsbX8wjKZPCy7ENj5HCYgOqzeSNLs/YrX2Vc7CQ=",
|
||||
"lastModified": 1737616857,
|
||||
"narHash": "sha256-6SugPt0lp1Gz7nV23FLmsmpfzgFItkSw7jpGftsDPWc=",
|
||||
"owner": "nayuki",
|
||||
"repo": "QR-Code-generator",
|
||||
"rev": "f40366c40d8d1956081f7ec643d240c02a81df52",
|
||||
"rev": "2c9044de6b049ca25cb3cd1649ed7e27aa055138",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -138,6 +138,8 @@
|
||||
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
name = "prism-launcher";
|
||||
|
||||
inputsFrom = [ packages'.prismlauncher-unwrapped ];
|
||||
|
||||
packages = with pkgs; [
|
||||
|
@ -125,6 +125,7 @@
|
||||
#include <FileSystem.h>
|
||||
#include <LocalPeer.h>
|
||||
|
||||
#include <QStringLiteral>
|
||||
#include <stdlib.h>
|
||||
#include <sys.h>
|
||||
#include "SysInfo.h"
|
||||
@ -153,11 +154,16 @@
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <QStyleHints>
|
||||
#include "WindowsConsole.h"
|
||||
#include "console/WindowsConsole.h"
|
||||
#endif
|
||||
|
||||
#include "console/Console.h"
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
@ -165,6 +171,63 @@ static const QLatin1String liveCheckFile("live.check");
|
||||
|
||||
PixmapCache* PixmapCache::s_instance = nullptr;
|
||||
|
||||
static bool isANSIColorConsole;
|
||||
|
||||
static QString defaultLogFormat = QStringLiteral(
|
||||
"%{time process}"
|
||||
" "
|
||||
"%{if-debug}Debug:%{endif}"
|
||||
"%{if-info}Info:%{endif}"
|
||||
"%{if-warning}Warning:%{endif}"
|
||||
"%{if-critical}Critical:%{endif}"
|
||||
"%{if-fatal}Fatal:%{endif}"
|
||||
" "
|
||||
"%{if-category}[%{category}] %{endif}"
|
||||
"%{message}"
|
||||
" "
|
||||
"(%{function}:%{line})");
|
||||
|
||||
#define ansi_reset "\x1b[0m"
|
||||
#define ansi_bold "\x1b[1m"
|
||||
#define ansi_reset_bold "\x1b[22m"
|
||||
#define ansi_faint "\x1b[2m"
|
||||
#define ansi_italic "\x1b[3m"
|
||||
#define ansi_red_fg "\x1b[31m"
|
||||
#define ansi_green_fg "\x1b[32m"
|
||||
#define ansi_yellow_fg "\x1b[33m"
|
||||
#define ansi_blue_fg "\x1b[34m"
|
||||
#define ansi_purple_fg "\x1b[35m"
|
||||
#define ansi_inverse "\x1b[7m"
|
||||
|
||||
// clang-format off
|
||||
static QString ansiLogFormat = QStringLiteral(
|
||||
ansi_faint "%{time process}" ansi_reset
|
||||
" "
|
||||
"%{if-debug}" ansi_bold ansi_green_fg "D:" ansi_reset "%{endif}"
|
||||
"%{if-info}" ansi_bold ansi_blue_fg "I:" ansi_reset "%{endif}"
|
||||
"%{if-warning}" ansi_bold ansi_yellow_fg "W:" ansi_reset_bold "%{endif}"
|
||||
"%{if-critical}" ansi_bold ansi_red_fg "C:" ansi_reset_bold "%{endif}"
|
||||
"%{if-fatal}" ansi_bold ansi_inverse ansi_red_fg "F:" ansi_reset_bold "%{endif}"
|
||||
" "
|
||||
"%{if-category}" ansi_bold "[%{category}]" ansi_reset_bold " %{endif}"
|
||||
"%{message}"
|
||||
" "
|
||||
ansi_reset ansi_faint "(%{function}:%{line})" ansi_reset
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
#undef ansi_inverse
|
||||
#undef ansi_purple_fg
|
||||
#undef ansi_blue_fg
|
||||
#undef ansi_yellow_fg
|
||||
#undef ansi_green_fg
|
||||
#undef ansi_red_fg
|
||||
#undef ansi_italic
|
||||
#undef ansi_faint
|
||||
#undef ansi_bold
|
||||
#undef ansi_reset_bold
|
||||
#undef ansi_reset
|
||||
|
||||
namespace {
|
||||
|
||||
/** This is used so that we can output to the log file in addition to the CLI. */
|
||||
@ -173,11 +236,24 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QSt
|
||||
static std::mutex loggerMutex;
|
||||
const std::lock_guard<std::mutex> lock(loggerMutex); // synchronized, QFile logFile is not thread-safe
|
||||
|
||||
if (isANSIColorConsole) {
|
||||
// ensure default is set for log file
|
||||
qSetMessagePattern(defaultLogFormat);
|
||||
}
|
||||
|
||||
QString out = qFormatLogMessage(type, context, msg);
|
||||
out += QChar::LineFeed;
|
||||
|
||||
APPLICATION->logFile->write(out.toUtf8());
|
||||
APPLICATION->logFile->flush();
|
||||
|
||||
if (isANSIColorConsole) {
|
||||
// format ansi for console;
|
||||
qSetMessagePattern(ansiLogFormat);
|
||||
out = qFormatLogMessage(type, context, msg);
|
||||
out += QChar::LineFeed;
|
||||
}
|
||||
|
||||
QTextStream(stderr) << out.toLocal8Bit();
|
||||
fflush(stderr);
|
||||
}
|
||||
@ -218,8 +294,18 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
// attach the parent console if stdout not already captured
|
||||
if (AttachWindowsConsole()) {
|
||||
consoleAttached = true;
|
||||
if (auto err = EnableAnsiSupport(); !err) {
|
||||
isANSIColorConsole = true;
|
||||
} else {
|
||||
std::cout << "Error setting up ansi console" << err.message() << std::endl;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (console::isConsole()) {
|
||||
isANSIColorConsole = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
setOrganizationName(BuildConfig.LAUNCHER_NAME);
|
||||
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
|
||||
setApplicationName(BuildConfig.LAUNCHER_NAME);
|
||||
@ -448,27 +534,14 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
return;
|
||||
}
|
||||
qInstallMessageHandler(appDebugOutput);
|
||||
|
||||
qSetMessagePattern(
|
||||
"%{time process}"
|
||||
" "
|
||||
"%{if-debug}D%{endif}"
|
||||
"%{if-info}I%{endif}"
|
||||
"%{if-warning}W%{endif}"
|
||||
"%{if-critical}C%{endif}"
|
||||
"%{if-fatal}F%{endif}"
|
||||
" "
|
||||
"|"
|
||||
" "
|
||||
"%{if-category}[%{category}]: %{endif}"
|
||||
"%{message}");
|
||||
qSetMessagePattern(defaultLogFormat);
|
||||
|
||||
bool foundLoggingRules = false;
|
||||
|
||||
auto logRulesFile = QStringLiteral("qtlogging.ini");
|
||||
auto logRulesPath = FS::PathCombine(dataPath, logRulesFile);
|
||||
|
||||
qDebug() << "Testing" << logRulesPath << "...";
|
||||
qInfo() << "Testing" << logRulesPath << "...";
|
||||
foundLoggingRules = QFile::exists(logRulesPath);
|
||||
|
||||
// search the dataPath()
|
||||
@ -476,7 +549,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
if (!foundLoggingRules && !isPortable() && dirParam.isEmpty() && dataDirEnv.isEmpty()) {
|
||||
logRulesPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, FS::PathCombine("..", logRulesFile));
|
||||
if (!logRulesPath.isEmpty()) {
|
||||
qDebug() << "Found" << logRulesPath << "...";
|
||||
qInfo() << "Found" << logRulesPath << "...";
|
||||
foundLoggingRules = true;
|
||||
}
|
||||
}
|
||||
@ -487,28 +560,28 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
#else
|
||||
logRulesPath = FS::PathCombine(m_rootPath, logRulesFile);
|
||||
#endif
|
||||
qDebug() << "Testing" << logRulesPath << "...";
|
||||
qInfo() << "Testing" << logRulesPath << "...";
|
||||
foundLoggingRules = QFile::exists(logRulesPath);
|
||||
}
|
||||
|
||||
if (foundLoggingRules) {
|
||||
// load and set logging rules
|
||||
qDebug() << "Loading logging rules from:" << logRulesPath;
|
||||
qInfo() << "Loading logging rules from:" << logRulesPath;
|
||||
QSettings loggingRules(logRulesPath, QSettings::IniFormat);
|
||||
loggingRules.beginGroup("Rules");
|
||||
QStringList rule_names = loggingRules.childKeys();
|
||||
QStringList rules;
|
||||
qDebug() << "Setting log rules:";
|
||||
qInfo() << "Setting log rules:";
|
||||
for (auto rule_name : rule_names) {
|
||||
auto rule = QString("%1=%2").arg(rule_name).arg(loggingRules.value(rule_name).toString());
|
||||
rules.append(rule);
|
||||
qDebug() << " " << rule;
|
||||
qInfo() << " " << rule;
|
||||
}
|
||||
auto rules_str = rules.join("\n");
|
||||
QLoggingCategory::setFilterRules(rules_str);
|
||||
}
|
||||
|
||||
qDebug() << "<> Log initialized.";
|
||||
qInfo() << "<> Log initialized.";
|
||||
}
|
||||
|
||||
{
|
||||
@ -525,33 +598,33 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << qPrintable(BuildConfig.LAUNCHER_DISPLAYNAME + ", " + QString(BuildConfig.LAUNCHER_COPYRIGHT).replace("\n", ", "));
|
||||
qDebug() << "Version : " << BuildConfig.printableVersionString();
|
||||
qDebug() << "Platform : " << BuildConfig.BUILD_PLATFORM;
|
||||
qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT;
|
||||
qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC;
|
||||
qDebug() << "Compiled for : " << BuildConfig.systemID();
|
||||
qDebug() << "Compiled by : " << BuildConfig.compilerID();
|
||||
qDebug() << "Build Artifact : " << BuildConfig.BUILD_ARTIFACT;
|
||||
qDebug() << "Updates Enabled : " << (updaterEnabled() ? "Yes" : "No");
|
||||
qInfo() << qPrintable(BuildConfig.LAUNCHER_DISPLAYNAME + ", " + QString(BuildConfig.LAUNCHER_COPYRIGHT).replace("\n", ", "));
|
||||
qInfo() << "Version : " << BuildConfig.printableVersionString();
|
||||
qInfo() << "Platform : " << BuildConfig.BUILD_PLATFORM;
|
||||
qInfo() << "Git commit : " << BuildConfig.GIT_COMMIT;
|
||||
qInfo() << "Git refspec : " << BuildConfig.GIT_REFSPEC;
|
||||
qInfo() << "Compiled for : " << BuildConfig.systemID();
|
||||
qInfo() << "Compiled by : " << BuildConfig.compilerID();
|
||||
qInfo() << "Build Artifact : " << BuildConfig.BUILD_ARTIFACT;
|
||||
qInfo() << "Updates Enabled : " << (updaterEnabled() ? "Yes" : "No");
|
||||
if (adjustedBy.size()) {
|
||||
qDebug() << "Work dir before adjustment : " << origcwdPath;
|
||||
qDebug() << "Work dir after adjustment : " << QDir::currentPath();
|
||||
qDebug() << "Adjusted by : " << adjustedBy;
|
||||
qInfo() << "Work dir before adjustment : " << origcwdPath;
|
||||
qInfo() << "Work dir after adjustment : " << QDir::currentPath();
|
||||
qInfo() << "Adjusted by : " << adjustedBy;
|
||||
} else {
|
||||
qDebug() << "Work dir : " << QDir::currentPath();
|
||||
qInfo() << "Work dir : " << QDir::currentPath();
|
||||
}
|
||||
qDebug() << "Binary path : " << binPath;
|
||||
qDebug() << "Application root path : " << m_rootPath;
|
||||
qInfo() << "Binary path : " << binPath;
|
||||
qInfo() << "Application root path : " << m_rootPath;
|
||||
if (!m_instanceIdToLaunch.isEmpty()) {
|
||||
qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
|
||||
qInfo() << "ID of instance to launch : " << m_instanceIdToLaunch;
|
||||
}
|
||||
if (!m_serverToJoin.isEmpty()) {
|
||||
qDebug() << "Address of server to join :" << m_serverToJoin;
|
||||
qInfo() << "Address of server to join :" << m_serverToJoin;
|
||||
} else if (!m_worldToJoin.isEmpty()) {
|
||||
qDebug() << "Name of the world to join :" << m_worldToJoin;
|
||||
qInfo() << "Name of the world to join :" << m_worldToJoin;
|
||||
}
|
||||
qDebug() << "<> Paths set.";
|
||||
qInfo() << "<> Paths set.";
|
||||
}
|
||||
|
||||
if (m_liveCheck) {
|
||||
@ -818,7 +891,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
|
||||
PixmapCache::setInstance(new PixmapCache(this));
|
||||
|
||||
qDebug() << "<> Settings loaded.";
|
||||
qInfo() << "<> Settings loaded.";
|
||||
}
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
@ -834,7 +907,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
QString user = settings()->get("ProxyUser").toString();
|
||||
QString pass = settings()->get("ProxyPass").toString();
|
||||
updateProxySettings(proxyTypeStr, addr, port, user, pass);
|
||||
qDebug() << "<> Network done.";
|
||||
qInfo() << "<> Network done.";
|
||||
}
|
||||
|
||||
// load translations
|
||||
@ -842,8 +915,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
m_translations.reset(new TranslationsModel("translations"));
|
||||
auto bcp47Name = m_settings->get("Language").toString();
|
||||
m_translations->selectLanguage(bcp47Name);
|
||||
qDebug() << "Your language is" << bcp47Name;
|
||||
qDebug() << "<> Translations loaded.";
|
||||
qInfo() << "Your language is" << bcp47Name;
|
||||
qInfo() << "<> Translations loaded.";
|
||||
}
|
||||
|
||||
// Instance icons
|
||||
@ -854,7 +927,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
m_icons.reset(new IconList(instFolders, setting->get().toString()));
|
||||
connect(setting.get(), &Setting::SettingChanged,
|
||||
[this](const Setting&, QVariant value) { m_icons->directoryChanged(value.toString()); });
|
||||
qDebug() << "<> Instance icons initialized.";
|
||||
qInfo() << "<> Instance icons initialized.";
|
||||
}
|
||||
|
||||
// Themes
|
||||
@ -866,25 +939,25 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
// instance path: check for problems with '!' in instance path and warn the user in the log
|
||||
// and remember that we have to show him a dialog when the gui starts (if it does so)
|
||||
QString instDir = InstDirSetting->get().toString();
|
||||
qDebug() << "Instance path : " << instDir;
|
||||
qInfo() << "Instance path : " << instDir;
|
||||
if (FS::checkProblemticPathJava(QDir(instDir))) {
|
||||
qWarning() << "Your instance path contains \'!\' and this is known to cause java problems!";
|
||||
}
|
||||
m_instances.reset(new InstanceList(m_settings, instDir, this));
|
||||
connect(InstDirSetting.get(), &Setting::SettingChanged, m_instances.get(), &InstanceList::on_InstFolderChanged);
|
||||
qDebug() << "Loading Instances...";
|
||||
qInfo() << "Loading Instances...";
|
||||
m_instances->loadList();
|
||||
qDebug() << "<> Instances loaded.";
|
||||
qInfo() << "<> Instances loaded.";
|
||||
}
|
||||
|
||||
// and accounts
|
||||
{
|
||||
m_accounts.reset(new AccountList(this));
|
||||
qDebug() << "Loading accounts...";
|
||||
qInfo() << "Loading accounts...";
|
||||
m_accounts->setListFilePath("accounts.json", true);
|
||||
m_accounts->loadList();
|
||||
m_accounts->fillQueue();
|
||||
qDebug() << "<> Accounts loaded.";
|
||||
qInfo() << "<> Accounts loaded.";
|
||||
}
|
||||
|
||||
// init the http meta cache
|
||||
@ -905,7 +978,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
m_metacache->addBase("meta", QDir("meta").absolutePath());
|
||||
m_metacache->addBase("java", QDir("cache/java").absolutePath());
|
||||
m_metacache->Load();
|
||||
qDebug() << "<> Cache initialized.";
|
||||
qInfo() << "<> Cache initialized.";
|
||||
}
|
||||
|
||||
// now we have network, download translation updates
|
||||
|
@ -99,7 +99,7 @@ set(CORE_SOURCES
|
||||
MTPixmapCache.h
|
||||
)
|
||||
if (UNIX AND NOT CYGWIN AND NOT APPLE)
|
||||
set(CORE_SOURCES
|
||||
set(CORE_SOURCES
|
||||
${CORE_SOURCES}
|
||||
|
||||
# MangoHud
|
||||
@ -589,8 +589,8 @@ set(ATLAUNCHER_SOURCES
|
||||
)
|
||||
|
||||
set(LINKEXE_SOURCES
|
||||
WindowsConsole.cpp
|
||||
WindowsConsole.h
|
||||
console/WindowsConsole.h
|
||||
console/WindowsConsole.cpp
|
||||
|
||||
filelink/FileLink.h
|
||||
filelink/FileLink.cpp
|
||||
@ -659,6 +659,14 @@ set(PRISMUPDATER_SOURCES
|
||||
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PRISMUPDATER_SOURCES
|
||||
console/WindowsConsole.h
|
||||
console/WindowsConsole.cpp
|
||||
${PRISMUPDATER_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
######## Logging categories ########
|
||||
|
||||
ecm_qt_declare_logging_category(CORE_SOURCES
|
||||
@ -786,6 +794,9 @@ SET(LAUNCHER_SOURCES
|
||||
SysInfo.h
|
||||
SysInfo.cpp
|
||||
|
||||
# console utils
|
||||
console/Console.h
|
||||
|
||||
# GUI - general utilities
|
||||
DesktopServices.h
|
||||
DesktopServices.cpp
|
||||
@ -1154,7 +1165,7 @@ SET(LAUNCHER_SOURCES
|
||||
)
|
||||
|
||||
if (NOT Apple)
|
||||
set(LAUNCHER_SOURCES
|
||||
set(LAUNCHER_SOURCES
|
||||
${LAUNCHER_SOURCES}
|
||||
|
||||
ui/dialogs/UpdateAvailableDialog.h
|
||||
@ -1164,8 +1175,8 @@ endif()
|
||||
|
||||
if(WIN32)
|
||||
set(LAUNCHER_SOURCES
|
||||
WindowsConsole.cpp
|
||||
WindowsConsole.h
|
||||
console/WindowsConsole.h
|
||||
console/WindowsConsole.cpp
|
||||
${LAUNCHER_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
@ -37,11 +37,7 @@ void DataMigrationTask::dryRunFinished()
|
||||
disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::dryRunFinished);
|
||||
disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::dryRunAborted);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
if (!m_copyFuture.isValid() || !m_copyFuture.result()) {
|
||||
#else
|
||||
if (!m_copyFuture.result()) {
|
||||
#endif
|
||||
emitFailed(tr("Failed to scan source path."));
|
||||
return;
|
||||
}
|
||||
@ -75,11 +71,7 @@ void DataMigrationTask::copyFinished()
|
||||
disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &DataMigrationTask::copyFinished);
|
||||
disconnect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &DataMigrationTask::copyAborted);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
if (!m_copyFuture.isValid() || !m_copyFuture.result()) {
|
||||
#else
|
||||
if (!m_copyFuture.result()) {
|
||||
#endif
|
||||
emitFailed(tr("Some paths could not be copied!"));
|
||||
return;
|
||||
}
|
||||
|
@ -282,11 +282,7 @@ void FileIgnoreProxy::loadBlockedPathsFromFile(const QString& fileName)
|
||||
}
|
||||
auto ignoreData = ignoreFile.readAll();
|
||||
auto string = QString::fromUtf8(ignoreData);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
setBlockedPaths(string.split('\n', Qt::SkipEmptyParts));
|
||||
#else
|
||||
setBlockedPaths(string.split('\n', QString::SkipEmptyParts));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileIgnoreProxy::saveBlockedPathsToFile(const QString& fileName)
|
||||
|
@ -679,9 +679,6 @@ bool deletePath(QString path)
|
||||
|
||||
bool trash(QString path, QString* pathInTrash)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
return false;
|
||||
#else
|
||||
// FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal
|
||||
if (DesktopServices::isFlatpak())
|
||||
return false;
|
||||
@ -690,7 +687,6 @@ bool trash(QString path, QString* pathInTrash)
|
||||
return false;
|
||||
#endif
|
||||
return QFile::moveToTrash(path, pathInTrash);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString PathCombine(const QString& path1, const QString& path2)
|
||||
@ -724,11 +720,7 @@ int pathDepth(const QString& path)
|
||||
|
||||
QFileInfo info(path);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
auto parts = QDir::toNativeSeparators(info.path()).split(QDir::separator(), QString::SkipEmptyParts);
|
||||
#else
|
||||
auto parts = QDir::toNativeSeparators(info.path()).split(QDir::separator(), Qt::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
int numParts = parts.length();
|
||||
numParts -= parts.count(".");
|
||||
@ -748,11 +740,7 @@ QString pathTruncate(const QString& path, int depth)
|
||||
return pathTruncate(trunc, depth);
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
auto parts = QDir::toNativeSeparators(trunc).split(QDir::separator(), QString::SkipEmptyParts);
|
||||
#else
|
||||
auto parts = QDir::toNativeSeparators(trunc).split(QDir::separator(), Qt::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
if (parts.startsWith(".") && !path.startsWith(".")) {
|
||||
parts.removeFirst();
|
||||
|
@ -139,64 +139,80 @@ bool GZip::zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes)
|
||||
return true;
|
||||
}
|
||||
|
||||
GZipStream::GZipStream(const QString& filePath) : GZipStream(new QFile(filePath)) {}
|
||||
|
||||
GZipStream::GZipStream(QFile* file) : m_file(file) {}
|
||||
|
||||
bool GZipStream::initStream()
|
||||
int inf(QFile* source, std::function<bool(const QByteArray&)> handleBlock)
|
||||
{
|
||||
memset(&m_strm, 0, sizeof(m_strm));
|
||||
return (inflateInit2(&m_strm, 16 + MAX_WBITS) == Z_OK);
|
||||
constexpr auto CHUNK = 16384;
|
||||
int ret;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
memset(&strm, 0, sizeof(strm));
|
||||
char in[CHUNK];
|
||||
unsigned char out[CHUNK];
|
||||
|
||||
ret = inflateInit2(&strm, (16 + MAX_WBITS));
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* decompress until deflate stream ends or end of file */
|
||||
do {
|
||||
strm.avail_in = source->read(in, CHUNK);
|
||||
if (source->error()) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
if (strm.avail_in == 0)
|
||||
break;
|
||||
strm.next_in = reinterpret_cast<Bytef*>(in);
|
||||
|
||||
/* run inflate() on input until output buffer not full */
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR; /* and fall through */
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (!handleBlock(QByteArray(reinterpret_cast<const char*>(out), have))) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
/* done when inflate() says it's done */
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
/* clean up and return */
|
||||
(void)inflateEnd(&strm);
|
||||
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
bool GZipStream::unzipBlockByBlock(QByteArray& uncompressedBytes)
|
||||
QString zerr(int ret)
|
||||
{
|
||||
uncompressedBytes.clear();
|
||||
if (!m_file->isOpen()) {
|
||||
if (!m_file->open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "Failed to open file:" << (m_file->fileName());
|
||||
return false;
|
||||
switch (ret) {
|
||||
case Z_ERRNO:
|
||||
return QObject::tr("error handling file");
|
||||
case Z_STREAM_ERROR:
|
||||
return QObject::tr("invalid compression level");
|
||||
case Z_DATA_ERROR:
|
||||
return QObject::tr("invalid or incomplete deflate data");
|
||||
case Z_MEM_ERROR:
|
||||
return QObject::tr("out of memory");
|
||||
case Z_VERSION_ERROR:
|
||||
return QObject::tr("zlib version mismatch!");
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_strm.state && !initStream()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray compressedBlock;
|
||||
unsigned int blockSize = 4096;
|
||||
|
||||
compressedBlock = m_file->read(blockSize);
|
||||
if (compressedBlock.isEmpty()) {
|
||||
return true; // End of file reached
|
||||
}
|
||||
|
||||
bool done = processBlock(compressedBlock, uncompressedBytes);
|
||||
if (inflateEnd(&m_strm) != Z_OK || !done) {
|
||||
return false;
|
||||
}
|
||||
return done;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GZipStream::processBlock(const QByteArray& compressedBlock, QByteArray& uncompressedBytes)
|
||||
QString GZip::readGzFileByBlocks(QFile* source, std::function<bool(const QByteArray&)> handleBlock)
|
||||
{
|
||||
m_strm.next_in = (Bytef*)compressedBlock.data();
|
||||
m_strm.avail_in = compressedBlock.size();
|
||||
|
||||
unsigned int uncompLength = uncompressedBytes.size();
|
||||
if (m_strm.total_out >= uncompLength) {
|
||||
uncompressedBytes.resize(uncompLength * 2);
|
||||
uncompLength *= 2;
|
||||
}
|
||||
|
||||
m_strm.next_out = reinterpret_cast<Bytef*>(uncompressedBytes.data() + m_strm.total_out);
|
||||
m_strm.avail_out = uncompLength - m_strm.total_out;
|
||||
|
||||
int err = inflate(&m_strm, Z_NO_FLUSH);
|
||||
if (err != Z_OK && err != Z_STREAM_END) {
|
||||
qWarning() << "Decompression failed with error code" << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
auto ret = inf(source, handleBlock);
|
||||
return zerr(ret);
|
||||
}
|
@ -1,28 +1,11 @@
|
||||
#pragma once
|
||||
#include <zlib.h>
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
|
||||
class GZip {
|
||||
public:
|
||||
static bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes);
|
||||
static bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes);
|
||||
};
|
||||
namespace GZip {
|
||||
|
||||
class GZipStream {
|
||||
public:
|
||||
explicit GZipStream(const QString& filePath);
|
||||
explicit GZipStream(QFile* file);
|
||||
bool unzip(const QByteArray& compressedBytes, QByteArray& uncompressedBytes);
|
||||
bool zip(const QByteArray& uncompressedBytes, QByteArray& compressedBytes);
|
||||
QString readGzFileByBlocks(QFile* source, std::function<bool(const QByteArray&)> handleBlock);
|
||||
|
||||
// Decompress the next block and return the decompressed data
|
||||
bool unzipBlockByBlock(QByteArray& uncompressedBytes);
|
||||
|
||||
private:
|
||||
bool initStream();
|
||||
|
||||
bool processBlock(const QByteArray& compressedBlock, QByteArray& uncompressedBytes);
|
||||
|
||||
private:
|
||||
QFile* m_file;
|
||||
z_stream m_strm;
|
||||
};
|
||||
} // namespace GZip
|
||||
|
@ -428,7 +428,7 @@ static QMap<InstanceId, InstanceLocator> getIdMapping(const QList<InstancePtr>&
|
||||
|
||||
QList<InstanceId> InstanceList::discoverInstances()
|
||||
{
|
||||
qDebug() << "Discovering instances in" << m_instDir;
|
||||
qInfo() << "Discovering instances in" << m_instDir;
|
||||
QList<InstanceId> out;
|
||||
QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden, QDirIterator::FollowSymlinks);
|
||||
while (iter.hasNext()) {
|
||||
@ -447,13 +447,9 @@ QList<InstanceId> InstanceList::discoverInstances()
|
||||
}
|
||||
auto id = dirInfo.fileName();
|
||||
out.append(id);
|
||||
qDebug() << "Found instance ID" << id;
|
||||
qInfo() << "Found instance ID" << id;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
instanceSet = QSet<QString>(out.begin(), out.end());
|
||||
#else
|
||||
instanceSet = out.toSet();
|
||||
#endif
|
||||
m_instancesProbed = true;
|
||||
return out;
|
||||
}
|
||||
@ -468,7 +464,7 @@ InstanceList::InstListError InstanceList::loadList()
|
||||
if (existingIds.contains(id)) {
|
||||
auto instPair = existingIds[id];
|
||||
existingIds.remove(id);
|
||||
qDebug() << "Should keep and soft-reload" << id;
|
||||
qInfo() << "Should keep and soft-reload" << id;
|
||||
} else {
|
||||
InstancePtr instPtr = loadInstance(id);
|
||||
if (instPtr) {
|
||||
|
@ -53,7 +53,7 @@ static inline QChar getNextChar(const QString& s, int location)
|
||||
int StringUtils::naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs)
|
||||
{
|
||||
int l1 = 0, l2 = 0;
|
||||
while (l1 <= s1.count() && l2 <= s2.count()) {
|
||||
while (l1 <= s1.size() && l2 <= s2.size()) {
|
||||
// skip spaces, tabs and 0's
|
||||
QChar c1 = getNextChar(s1, l1);
|
||||
while (c1.isSpace())
|
||||
|
@ -72,22 +72,14 @@ class Version {
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
auto numPart = QStringView{ m_fullString }.left(cutoff);
|
||||
#else
|
||||
auto numPart = m_fullString.leftRef(cutoff);
|
||||
#endif
|
||||
|
||||
if (!numPart.isEmpty()) {
|
||||
m_isNull = false;
|
||||
m_numPart = numPart.toInt();
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
auto stringPart = QStringView{ m_fullString }.mid(cutoff);
|
||||
#else
|
||||
auto stringPart = m_fullString.midRef(cutoff);
|
||||
#endif
|
||||
|
||||
if (!stringPart.isEmpty()) {
|
||||
m_isNull = false;
|
||||
|
33
launcher/console/Console.h
Normal file
33
launcher/console/Console.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <ostream>
|
||||
#if defined Q_OS_WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
namespace console {
|
||||
|
||||
inline bool isConsole()
|
||||
{
|
||||
#if defined Q_OS_WIN32
|
||||
DWORD procIDs[2];
|
||||
DWORD maxCount = 2;
|
||||
DWORD result = GetConsoleProcessList((LPDWORD)procIDs, maxCount);
|
||||
return result > 1;
|
||||
#else
|
||||
if (isatty(fileno(stdout))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace console
|
@ -16,13 +16,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "WindowsConsole.h"
|
||||
#include <system_error>
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
void RedirectHandle(DWORD handle, FILE* stream, const char* mode)
|
||||
@ -126,3 +131,29 @@ bool AttachWindowsConsole()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code EnableAnsiSupport()
|
||||
{
|
||||
// ref: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
|
||||
// Using `CreateFileW("CONOUT$", ...)` to retrieve the console handle works correctly even if STDOUT and/or STDERR are redirected
|
||||
HANDLE console_handle = CreateFileW(L"CONOUT$", FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (console_handle == INVALID_HANDLE_VALUE) {
|
||||
return std::error_code(GetLastError(), std::system_category());
|
||||
}
|
||||
|
||||
// ref: https://docs.microsoft.com/en-us/windows/console/getconsolemode
|
||||
DWORD console_mode;
|
||||
if (0 == GetConsoleMode(console_handle, &console_mode)) {
|
||||
return std::error_code(GetLastError(), std::system_category());
|
||||
}
|
||||
|
||||
// VT processing not already enabled?
|
||||
if ((console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0) {
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
if (0 == SetConsoleMode(console_handle, console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
|
||||
return std::error_code(GetLastError(), std::system_category());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
@ -21,5 +21,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <system_error>
|
||||
|
||||
void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr);
|
||||
bool AttachWindowsConsole();
|
||||
std::error_code EnableAnsiSupport();
|
@ -37,7 +37,10 @@
|
||||
#include <sys.h>
|
||||
|
||||
#if defined Q_OS_WIN32
|
||||
#include "WindowsConsole.h"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include "console/WindowsConsole.h"
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
|
@ -137,11 +137,7 @@ QString formatName(const QDir& iconsDir, const QFileInfo& iconFile)
|
||||
/// Split into a separate function because the preprocessing impedes readability
|
||||
QSet<QString> toStringSet(const QList<QString>& list)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QSet<QString> set(list.begin(), list.end());
|
||||
#else
|
||||
QSet<QString> set = list.toSet();
|
||||
#endif
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -137,11 +137,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
|
||||
|
||||
QMap<QString, QString> results;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList lines = m_stdout.split("\n", Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
|
||||
#endif
|
||||
for (QString line : lines) {
|
||||
line = line.trimmed();
|
||||
// NOTE: workaround for GH-4125, where garbage is getting printed into stdout on bedrock linux
|
||||
@ -149,11 +145,7 @@ void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
|
||||
continue;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
auto parts = line.split('=', Qt::SkipEmptyParts);
|
||||
#else
|
||||
auto parts = line.split('=', QString::SkipEmptyParts);
|
||||
#endif
|
||||
if (parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty()) {
|
||||
continue;
|
||||
} else {
|
||||
|
@ -49,14 +49,10 @@ void PostLaunchCommand::executeTask()
|
||||
{
|
||||
auto cmd = m_parent->substituteVariables(m_command);
|
||||
emit logLine(tr("Running Post-Launch command: %1").arg(cmd), MessageLevel::Launcher);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
auto args = QProcess::splitCommand(cmd);
|
||||
|
||||
const QString program = args.takeFirst();
|
||||
m_process.start(program, args);
|
||||
#else
|
||||
m_process.start(cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PostLaunchCommand::on_state(LoggedProcess::State state)
|
||||
|
@ -49,13 +49,9 @@ void PreLaunchCommand::executeTask()
|
||||
{
|
||||
auto cmd = m_parent->substituteVariables(m_command);
|
||||
emit logLine(tr("Running Pre-Launch command: %1").arg(cmd), MessageLevel::Launcher);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
auto args = QProcess::splitCommand(cmd);
|
||||
const QString program = args.takeFirst();
|
||||
m_process.start(program, args);
|
||||
#else
|
||||
m_process.start(cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PreLaunchCommand::on_state(LoggedProcess::State state)
|
||||
|
@ -757,11 +757,7 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, Mine
|
||||
token_mapping["assets_root"] = absAssetsDir;
|
||||
token_mapping["assets_index_name"] = assets->id;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList parts = args_pattern.split(' ', Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
|
||||
#endif
|
||||
for (int i = 0; i < parts.length(); i++) {
|
||||
parts[i] = replaceTokensIn(parts[i], token_mapping);
|
||||
}
|
||||
@ -816,11 +812,7 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftT
|
||||
auto mainWindow = qobject_cast<QMainWindow*>(w);
|
||||
if (mainWindow) {
|
||||
auto m = mainWindow->windowHandle()->frameMargins();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
screenGeometry = screenGeometry.shrunkBy(m);
|
||||
#else
|
||||
screenGeometry = { screenGeometry.width() - m.left() - m.right(), screenGeometry.height() - m.top() - m.bottom() };
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -645,11 +645,7 @@ void PackProfile::move(const int index, const MoveDirection direction)
|
||||
return;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||
d->components.swapItemsAt(index, theirIndex);
|
||||
#else
|
||||
d->components.swap(index, theirIndex);
|
||||
#endif
|
||||
endMoveRows();
|
||||
invalidateLaunchProfile();
|
||||
scheduleSave();
|
||||
|
@ -309,11 +309,7 @@ class WorldMimeData : public QMimeData {
|
||||
QStringList formats() const { return QMimeData::formats() << "text/uri-list"; }
|
||||
|
||||
protected:
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QVariant retrieveData(const QString& mimetype, QMetaType type) const
|
||||
#else
|
||||
QVariant retrieveData(const QString& mimetype, QVariant::Type type) const
|
||||
#endif
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
for (auto& world : m_worlds) {
|
||||
|
@ -106,11 +106,7 @@ QPixmap MinecraftAccount::getFace() const
|
||||
return QPixmap();
|
||||
}
|
||||
QPixmap skin = QPixmap(8, 8);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
skin.fill(QColorConstants::Transparent);
|
||||
#else
|
||||
skin.fill(QColor(0, 0, 0, 0));
|
||||
#endif
|
||||
QPainter painter(&skin);
|
||||
painter.drawPixmap(0, 0, skinTexture.copy(8, 8, 8, 8));
|
||||
painter.drawPixmap(0, 0, skinTexture.copy(40, 8, 8, 8));
|
||||
@ -290,13 +286,8 @@ QUuid MinecraftAccount::uuidFromUsername(QString username)
|
||||
// basically a reimplementation of Java's UUID#nameUUIDFromBytes
|
||||
QByteArray digest = QCryptographicHash::hash(input, QCryptographicHash::Md5);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
auto bOr = [](QByteArray& array, int index, char value) { array[index] = array.at(index) | value; };
|
||||
auto bAnd = [](QByteArray& array, int index, char value) { array[index] = array.at(index) & value; };
|
||||
#else
|
||||
auto bOr = [](QByteArray& array, qsizetype index, char value) { array[index] |= value; };
|
||||
auto bAnd = [](QByteArray& array, qsizetype index, char value) { array[index] &= value; };
|
||||
#endif
|
||||
bAnd(digest, 6, (char)0x0f); // clear version
|
||||
bOr(digest, 6, (char)0x30); // set to version 3
|
||||
bAnd(digest, 8, (char)0x3f); // clear variant
|
||||
|
@ -315,11 +315,7 @@ bool parseMinecraftProfileMojang(QByteArray& data, MinecraftProfile& output)
|
||||
|
||||
auto value = pObj.value("value");
|
||||
if (value.isString()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
texturePayload = QByteArray::fromBase64(value.toString().toUtf8(), QByteArray::AbortOnBase64DecodingErrors);
|
||||
#else
|
||||
texturePayload = QByteArray::fromBase64(value.toString().toUtf8());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!texturePayload.isEmpty()) {
|
||||
|
@ -168,13 +168,8 @@ void MSAStep::perform()
|
||||
m_oauth2.setRefreshToken(m_data->msaToken.refresh_token);
|
||||
m_oauth2.refreshAccessToken();
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // QMultiMap param changed in 6.0
|
||||
m_oauth2.setModifyParametersFunction(
|
||||
[](QAbstractOAuth::Stage stage, QMultiMap<QString, QVariant>* map) { map->insert("prompt", "select_account"); });
|
||||
#else
|
||||
m_oauth2.setModifyParametersFunction(
|
||||
[](QAbstractOAuth::Stage stage, QMap<QString, QVariant>* map) { map->insert("prompt", "select_account"); });
|
||||
#endif
|
||||
|
||||
*m_data = AccountData();
|
||||
m_data->msaClientID = m_clientId;
|
||||
|
@ -363,16 +363,11 @@ void ResourceFolderModel::onUpdateSucceeded()
|
||||
|
||||
auto& new_resources = update_results->resources;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
auto current_list = m_resources_index.keys();
|
||||
QSet<QString> current_set(current_list.begin(), current_list.end());
|
||||
|
||||
auto new_list = new_resources.keys();
|
||||
QSet<QString> new_set(new_list.begin(), new_list.end());
|
||||
#else
|
||||
QSet<QString> current_set(m_resources_index.keys().toSet());
|
||||
QSet<QString> new_set(new_resources.keys().toSet());
|
||||
#endif
|
||||
|
||||
applyUpdates(current_set, new_set, new_resources);
|
||||
}
|
||||
|
@ -678,13 +678,8 @@ void PackInstallTask::extractConfigs()
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload<QString, QString>::of(MMCZip::extractDir), archivePath,
|
||||
extractDir.absolutePath() + "/minecraft");
|
||||
#else
|
||||
m_extractFuture =
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft");
|
||||
#endif
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [this]() { downloadMods(); });
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [this]() { emitAborted(); });
|
||||
m_extractFutureWatcher.setFuture(m_extractFuture);
|
||||
@ -897,13 +892,8 @@ void PackInstallTask::onModsDownloaded()
|
||||
jobPtr.reset();
|
||||
|
||||
if (!modsToExtract.empty() || !modsToDecomp.empty() || !modsToCopy.empty()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
m_modExtractFuture =
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), &PackInstallTask::extractMods, this, modsToExtract, modsToDecomp, modsToCopy);
|
||||
#else
|
||||
m_modExtractFuture =
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy);
|
||||
#endif
|
||||
connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onModsExtracted);
|
||||
connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &PackInstallTask::emitAborted);
|
||||
m_modExtractFutureWatcher.setFuture(m_modExtractFuture);
|
||||
|
@ -79,7 +79,7 @@ void PackFetchTask::fetchPrivate(const QStringList& toFetch)
|
||||
QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode] {
|
||||
ModpackList packs;
|
||||
parseAndAddPacks(*data, PackType::Private, packs);
|
||||
foreach (Modpack currentPack, packs) {
|
||||
for (auto& currentPack : packs) {
|
||||
currentPack.packCode = packCode;
|
||||
emit privateFileDownloadFinished(currentPack);
|
||||
}
|
||||
|
@ -108,13 +108,8 @@ void PackInstallTask::unzip()
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload<QString, QString>::of(MMCZip::extractDir), archivePath,
|
||||
extractDir.absolutePath() + "/unzip");
|
||||
#else
|
||||
m_extractFuture =
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
|
||||
#endif
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onUnzipFinished);
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &PackInstallTask::onUnzipCanceled);
|
||||
m_extractFutureWatcher.setFuture(m_extractFuture);
|
||||
@ -165,7 +160,7 @@ void PackInstallTask::install()
|
||||
// we only care about the libs
|
||||
QJsonArray libs = doc.object().value("libraries").toArray();
|
||||
|
||||
foreach (const QJsonValue& value, libs) {
|
||||
for (const auto& value : libs) {
|
||||
QString nameValue = value.toObject().value("name").toString();
|
||||
if (!nameValue.startsWith("net.minecraftforge")) {
|
||||
continue;
|
||||
|
@ -44,12 +44,8 @@ namespace LegacyFTB {
|
||||
void PrivatePackManager::load()
|
||||
{
|
||||
try {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
auto foo = QString::fromUtf8(FS::read(m_filename)).split('\n', Qt::SkipEmptyParts);
|
||||
currentPacks = QSet<QString>(foo.begin(), foo.end());
|
||||
#else
|
||||
currentPacks = QString::fromUtf8(FS::read(m_filename)).split('\n', QString::SkipEmptyParts).toSet();
|
||||
#endif
|
||||
|
||||
dirty = false;
|
||||
} catch (...) {
|
||||
|
@ -104,12 +104,10 @@ void NetRequest::executeTask()
|
||||
header_proxy->writeHeaders(request);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
#if defined(LAUNCHER_APPLICATION)
|
||||
request.setTransferTimeout(APPLICATION->settings()->get("RequestTimeout").toInt() * 1000);
|
||||
#else
|
||||
request.setTransferTimeout();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
m_last_progress_time = m_clock.now();
|
||||
@ -122,11 +120,7 @@ void NetRequest::executeTask()
|
||||
connect(rep, &QNetworkReply::uploadProgress, this, &NetRequest::onProgress);
|
||||
connect(rep, &QNetworkReply::downloadProgress, this, &NetRequest::onProgress);
|
||||
connect(rep, &QNetworkReply::finished, this, &NetRequest::downloadFinished);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15
|
||||
connect(rep, &QNetworkReply::errorOccurred, this, &NetRequest::downloadError);
|
||||
#else
|
||||
connect(rep, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, &NetRequest::downloadError);
|
||||
#endif
|
||||
connect(rep, &QNetworkReply::sslErrors, this, &NetRequest::sslErrors);
|
||||
connect(rep, &QNetworkReply::readyRead, this, &NetRequest::downloadReadyRead);
|
||||
}
|
||||
@ -323,11 +317,7 @@ auto NetRequest::abort() -> bool
|
||||
{
|
||||
m_state = State::AbortedByUser;
|
||||
if (m_reply) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15
|
||||
disconnect(m_reply.get(), &QNetworkReply::errorOccurred, nullptr, nullptr);
|
||||
#else
|
||||
disconnect(m_reply.get(), QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), nullptr, nullptr);
|
||||
#endif
|
||||
m_reply->abort();
|
||||
}
|
||||
return true;
|
||||
|
@ -130,11 +130,7 @@ void PasteUpload::executeTask()
|
||||
connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
|
||||
connect(rep, &QNetworkReply::finished, this, &PasteUpload::downloadFinished);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
connect(rep, &QNetworkReply::errorOccurred, this, &PasteUpload::downloadError);
|
||||
#else
|
||||
connect(rep, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, &PasteUpload::downloadError);
|
||||
#endif
|
||||
|
||||
m_reply = std::shared_ptr<QNetworkReply>(rep);
|
||||
|
||||
|
@ -480,7 +480,7 @@ bool TranslationsModel::selectLanguage(QString key)
|
||||
bool successful = false;
|
||||
// FIXME: this is likely never present. FIX IT.
|
||||
d->m_qt_translator.reset(new QTranslator());
|
||||
if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
|
||||
if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
|
||||
qDebug() << "Loading Qt Language File for" << langCode.toLocal8Bit().constData() << "...";
|
||||
if (!QCoreApplication::installTranslator(d->m_qt_translator.get())) {
|
||||
qCritical() << "Loading Qt Language File failed.";
|
||||
|
@ -721,7 +721,7 @@ void MainWindow::changeActiveAccount()
|
||||
QAction* sAction = (QAction*)sender();
|
||||
|
||||
// Profile's associated Mojang username
|
||||
if (sAction->data().type() != QVariant::Type::Int)
|
||||
if (sAction->data().typeId() != QMetaType::Int)
|
||||
return;
|
||||
|
||||
QVariant action_data = sAction->data();
|
||||
@ -811,11 +811,7 @@ void MainWindow::updateNewsLabel()
|
||||
|
||||
QList<int> stringToIntList(const QString& string)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList split = string.split(',', Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList split = string.split(',', QString::SkipEmptyParts);
|
||||
#endif
|
||||
QList<int> out;
|
||||
for (int i = 0; i < split.size(); ++i) {
|
||||
out.append(split.at(i).toInt());
|
||||
|
@ -136,11 +136,7 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup,
|
||||
if (APPLICATION->settings()->get("NewInstanceGeometry").isValid()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("NewInstanceGeometry").toByteArray()));
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
auto screen = parent->screen();
|
||||
#else
|
||||
auto screen = QGuiApplication::primaryScreen();
|
||||
#endif
|
||||
auto geometry = screen->availableSize();
|
||||
resize(width(), qMin(geometry.height() - 50, 710));
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ void SkinOpenGLWindow::mousePressEvent(QMouseEvent* e)
|
||||
void SkinOpenGLWindow::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (m_isMousePressed) {
|
||||
int dx = event->x() - m_mousePosition.x();
|
||||
int dy = event->y() - m_mousePosition.y();
|
||||
int dx = event->position().x() - m_mousePosition.x();
|
||||
int dy = event->position().y() - m_mousePosition.y();
|
||||
|
||||
m_yaw += dx * 0.5f;
|
||||
m_pitch += dy * 0.5f;
|
||||
|
@ -400,12 +400,8 @@ void InstanceView::mouseReleaseEvent(QMouseEvent* event)
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit clicked(index);
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
if (m_pressedAlreadySelected) {
|
||||
option.state |= QStyle::State_Selected;
|
||||
}
|
||||
@ -422,7 +418,7 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index)) {
|
||||
QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(), event->screenPos(), event->button(),
|
||||
QMouseEvent me(QEvent::MouseButtonPress, event->position(), event->scenePosition(), event->globalPosition(), event->button(),
|
||||
event->buttons(), event->modifiers());
|
||||
mousePressEvent(&me);
|
||||
return;
|
||||
@ -431,12 +427,8 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
QPersistentModelIndex persistent = index;
|
||||
emit doubleClicked(persistent);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
if ((model()->flags(index) & Qt::ItemIsEnabled) && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) {
|
||||
emit activated(index);
|
||||
}
|
||||
@ -472,12 +464,8 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
painter.setOpacity(1.0);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
option.widget = this;
|
||||
|
||||
if (model()->rowCount() == 0) {
|
||||
@ -610,7 +598,7 @@ void InstanceView::dragEnterEvent(QDragEnterEvent* event)
|
||||
if (!isDragEventAccepted(event)) {
|
||||
return;
|
||||
}
|
||||
m_lastDragPosition = event->pos() + offset();
|
||||
m_lastDragPosition = event->position().toPoint() + offset();
|
||||
viewport()->update();
|
||||
event->accept();
|
||||
}
|
||||
@ -622,7 +610,7 @@ void InstanceView::dragMoveEvent(QDragMoveEvent* event)
|
||||
if (!isDragEventAccepted(event)) {
|
||||
return;
|
||||
}
|
||||
m_lastDragPosition = event->pos() + offset();
|
||||
m_lastDragPosition = event->position().toPoint() + offset();
|
||||
viewport()->update();
|
||||
event->accept();
|
||||
}
|
||||
@ -648,7 +636,7 @@ void InstanceView::dropEvent(QDropEvent* event)
|
||||
|
||||
if (event->source() == this) {
|
||||
if (event->possibleActions() & Qt::MoveAction) {
|
||||
std::pair<VisualGroup*, VisualGroup::HitResults> dropPos = rowDropPos(event->pos());
|
||||
std::pair<VisualGroup*, VisualGroup::HitResults> dropPos = rowDropPos(event->position().toPoint());
|
||||
const VisualGroup* group = dropPos.first;
|
||||
auto hitResult = dropPos.second;
|
||||
|
||||
@ -732,12 +720,8 @@ QRect InstanceView::geometryRect(const QModelIndex& index) const
|
||||
int x = pos.first;
|
||||
// int y = pos.second;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
|
||||
QRect out;
|
||||
out.setTop(cat->verticalPosition() + cat->headerHeight() + 5 + cat->rowTopOf(index));
|
||||
@ -784,12 +768,8 @@ QPixmap InstanceView::renderToPixmap(const QModelIndexList& indices, QRect* r) c
|
||||
QPixmap pixmap(r->size());
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
#else
|
||||
QStyleOptionViewItem option = viewOptions();
|
||||
#endif
|
||||
option.state |= QStyle::State_Selected;
|
||||
for (int j = 0; j < paintPairs.count(); ++j) {
|
||||
option.rect = paintPairs.at(j).first.translated(-r->topLeft());
|
||||
|
@ -73,12 +73,8 @@ void VisualGroup::update()
|
||||
positionInRow = 0;
|
||||
maxRowHeight = 0;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QStyleOptionViewItem viewItemOption;
|
||||
view->initViewItemOption(&viewItemOption);
|
||||
#else
|
||||
QStyleOptionViewItem viewItemOption = view->viewOptions();
|
||||
#endif
|
||||
|
||||
auto itemHeight = view->itemDelegate()->sizeHint(viewItemOption, item).height();
|
||||
if (itemHeight > maxRowHeight) {
|
||||
|
@ -174,48 +174,6 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
|
||||
}
|
||||
}
|
||||
|
||||
class ReadLineAbstract {
|
||||
public:
|
||||
ReadLineAbstract(QFile* file) : m_file(file)
|
||||
{
|
||||
if (file->fileName().endsWith(".gz"))
|
||||
m_gz = new GZipStream(file);
|
||||
}
|
||||
~ReadLineAbstract() { delete m_gz; }
|
||||
|
||||
QString readLine()
|
||||
{
|
||||
if (!m_gz)
|
||||
return QString::fromUtf8(m_file->readLine());
|
||||
QString line;
|
||||
for (;;) {
|
||||
if (!m_decodedData.isEmpty()) {
|
||||
int newlineIndex = m_decodedData.indexOf('\n');
|
||||
if (newlineIndex != -1) {
|
||||
line += QString::fromUtf8(m_decodedData).left(newlineIndex);
|
||||
m_decodedData.remove(0, newlineIndex + 1);
|
||||
return line;
|
||||
}
|
||||
|
||||
line += QString::fromUtf8(m_decodedData);
|
||||
m_decodedData.clear();
|
||||
}
|
||||
|
||||
if (!m_gz->unzipBlockByBlock(m_decodedData)) { // If error occurs during unzipping
|
||||
m_decodedData.clear();
|
||||
return QObject::tr("The content of the file(%1) could not be decoded.").arg(m_file->fileName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool done() { return m_gz ? m_decodedData.isEmpty() : m_file->atEnd(); }
|
||||
|
||||
private:
|
||||
QFile* m_file;
|
||||
GZipStream* m_gz = nullptr;
|
||||
QByteArray m_decodedData;
|
||||
};
|
||||
|
||||
void OtherLogsPage::on_btnReload_clicked()
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
@ -243,15 +201,9 @@ void OtherLogsPage::on_btnReload_clicked()
|
||||
showTooBig();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadLineAbstract stream(&file);
|
||||
|
||||
// Try to determine a level for each line
|
||||
ui->text->clear();
|
||||
ui->text->setModel(nullptr);
|
||||
m_model->clear();
|
||||
auto line = stream.readLine();
|
||||
while (!stream.done()) { // just read until the model is full or the file ended
|
||||
auto handleLine = [this](QString line) {
|
||||
if (line.isEmpty())
|
||||
return false;
|
||||
if (line.back() == '\n')
|
||||
line = line.remove(line.size() - 1, 1);
|
||||
MessageLevel::Enum level = MessageLevel::Unknown;
|
||||
@ -268,10 +220,40 @@ void OtherLogsPage::on_btnReload_clicked()
|
||||
}
|
||||
|
||||
m_model->append(level, line);
|
||||
if (m_model->isOverFlow())
|
||||
break;
|
||||
return m_model->isOverFlow();
|
||||
};
|
||||
|
||||
line = stream.readLine();
|
||||
// Try to determine a level for each line
|
||||
ui->text->clear();
|
||||
ui->text->setModel(nullptr);
|
||||
m_model->clear();
|
||||
if (file.fileName().endsWith(".gz")) {
|
||||
QString line;
|
||||
auto error = GZip::readGzFileByBlocks(&file, [&line, handleLine](const QByteArray& d) {
|
||||
auto block = d;
|
||||
int newlineIndex = block.indexOf('\n');
|
||||
while (newlineIndex != -1) {
|
||||
line += QString::fromUtf8(block).left(newlineIndex);
|
||||
block.remove(0, newlineIndex + 1);
|
||||
if (handleLine(line)) {
|
||||
line.clear();
|
||||
return false;
|
||||
}
|
||||
line.clear();
|
||||
newlineIndex = block.indexOf('\n');
|
||||
}
|
||||
line += QString::fromUtf8(block);
|
||||
return true;
|
||||
});
|
||||
if (!error.isEmpty()) {
|
||||
setPlainText(tr("The file (%1) encountered an error when reading: %2.").arg(file.fileName(), error));
|
||||
return;
|
||||
} else if (!line.isEmpty()) {
|
||||
handleLine(line);
|
||||
}
|
||||
} else {
|
||||
while (!file.atEnd() && !handleLine(QString::fromUtf8(file.readLine()))) {
|
||||
}
|
||||
}
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->scrollToBottom();
|
||||
|
@ -255,11 +255,7 @@ class ServersModel : public QAbstractListModel {
|
||||
return false;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||
m_servers.swapItemsAt(row - 1, row);
|
||||
#else
|
||||
m_servers.swap(row - 1, row);
|
||||
#endif
|
||||
endMoveRows();
|
||||
scheduleSave();
|
||||
return true;
|
||||
@ -275,11 +271,7 @@ class ServersModel : public QAbstractListModel {
|
||||
return false;
|
||||
}
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
|
||||
m_servers.swapItemsAt(row + 1, row);
|
||||
#else
|
||||
m_servers.swap(row + 1, row);
|
||||
#endif
|
||||
endMoveRows();
|
||||
scheduleSave();
|
||||
return true;
|
||||
|
@ -46,11 +46,8 @@
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include "console/WindowsConsole.h"
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
@ -87,113 +84,13 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QSt
|
||||
}
|
||||
}
|
||||
|
||||
#if defined Q_OS_WIN32
|
||||
|
||||
// taken from https://stackoverflow.com/a/25927081
|
||||
// getting a proper output to console with redirection support on windows is apparently hell
|
||||
void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr)
|
||||
{
|
||||
// Re-initialize the C runtime "FILE" handles with clean handles bound to "nul". We do this because it has been
|
||||
// observed that the file number of our standard handle file objects can be assigned internally to a value of -2
|
||||
// when not bound to a valid target, which represents some kind of unknown internal invalid state. In this state our
|
||||
// call to "_dup2" fails, as it specifically tests to ensure that the target file number isn't equal to this value
|
||||
// before allowing the operation to continue. We can resolve this issue by first "re-opening" the target files to
|
||||
// use the "nul" device, which will place them into a valid state, after which we can redirect them to our target
|
||||
// using the "_dup2" function.
|
||||
if (bindStdIn) {
|
||||
FILE* dummyFile;
|
||||
freopen_s(&dummyFile, "nul", "r", stdin);
|
||||
}
|
||||
if (bindStdOut) {
|
||||
FILE* dummyFile;
|
||||
freopen_s(&dummyFile, "nul", "w", stdout);
|
||||
}
|
||||
if (bindStdErr) {
|
||||
FILE* dummyFile;
|
||||
freopen_s(&dummyFile, "nul", "w", stderr);
|
||||
}
|
||||
|
||||
// Redirect unbuffered stdin from the current standard input handle
|
||||
if (bindStdIn) {
|
||||
HANDLE stdHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (stdHandle != INVALID_HANDLE_VALUE) {
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
if (fileDescriptor != -1) {
|
||||
FILE* file = _fdopen(fileDescriptor, "r");
|
||||
if (file != NULL) {
|
||||
int dup2Result = _dup2(_fileno(file), _fileno(stdin));
|
||||
if (dup2Result == 0) {
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect unbuffered stdout to the current standard output handle
|
||||
if (bindStdOut) {
|
||||
HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (stdHandle != INVALID_HANDLE_VALUE) {
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
if (fileDescriptor != -1) {
|
||||
FILE* file = _fdopen(fileDescriptor, "w");
|
||||
if (file != NULL) {
|
||||
int dup2Result = _dup2(_fileno(file), _fileno(stdout));
|
||||
if (dup2Result == 0) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect unbuffered stderr to the current standard error handle
|
||||
if (bindStdErr) {
|
||||
HANDLE stdHandle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if (stdHandle != INVALID_HANDLE_VALUE) {
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
if (fileDescriptor != -1) {
|
||||
FILE* file = _fdopen(fileDescriptor, "w");
|
||||
if (file != NULL) {
|
||||
int dup2Result = _dup2(_fileno(file), _fileno(stderr));
|
||||
if (dup2Result == 0) {
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the error state for each of the C++ standard stream objects. We need to do this, as attempts to access the
|
||||
// standard streams before they refer to a valid target will cause the iostream objects to enter an error state. In
|
||||
// versions of Visual Studio after 2005, this seems to always occur during startup regardless of whether anything
|
||||
// has been read from or written to the targets or not.
|
||||
if (bindStdIn) {
|
||||
std::wcin.clear();
|
||||
std::cin.clear();
|
||||
}
|
||||
if (bindStdOut) {
|
||||
std::wcout.clear();
|
||||
std::cout.clear();
|
||||
}
|
||||
if (bindStdErr) {
|
||||
std::wcerr.clear();
|
||||
std::cerr.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, argv)
|
||||
{
|
||||
#if defined Q_OS_WIN32
|
||||
// attach the parent console if stdout not already captured
|
||||
auto stdout_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
if (stdout_type == FILE_TYPE_CHAR || stdout_type == FILE_TYPE_UNKNOWN) {
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
BindCrtHandlesToStdHandles(true, true, true);
|
||||
if (AttachWindowsConsole()) {
|
||||
consoleAttached = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
setOrganizationName(BuildConfig.LAUNCHER_NAME);
|
||||
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
|
||||
|
@ -1,9 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(LocalPeer)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 5)
|
||||
find_package(Qt5 COMPONENTS Core Network REQUIRED)
|
||||
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
find_package(Qt6 COMPONENTS Core Network Core5Compat REQUIRED)
|
||||
list(APPEND LocalPeer_LIBS Qt${QT_VERSION_MAJOR}::Core5Compat)
|
||||
endif()
|
||||
|
@ -75,7 +75,7 @@ ApplicationId ApplicationId::fromTraditionalApp()
|
||||
prefix.remove(QRegularExpression("[^a-zA-Z]"));
|
||||
prefix.truncate(6);
|
||||
QByteArray idc = protoId.toUtf8();
|
||||
quint16 idNum = qChecksum(idc.constData(), idc.size());
|
||||
quint16 idNum = qChecksum(idc);
|
||||
auto socketName = QLatin1String("pl") + prefix + QLatin1Char('-') + QString::number(idNum, 16).left(12);
|
||||
#if defined(Q_OS_WIN)
|
||||
if (!pProcessIdToSessionId) {
|
||||
|
@ -97,6 +97,19 @@ public final class StandardLauncher extends AbstractLauncher {
|
||||
gameArgs.add(worldName);
|
||||
}
|
||||
|
||||
StringBuilder joinedGameArgs = new StringBuilder();
|
||||
for (String gameArg : gameArgs) {
|
||||
if (joinedGameArgs.length() > 0) {
|
||||
joinedGameArgs.append('\u001F'); // unit separator, designed for this purpose
|
||||
}
|
||||
joinedGameArgs.append(gameArg);
|
||||
}
|
||||
|
||||
// pass the real main class and game arguments in so mods can access them
|
||||
System.setProperty("org.prismlauncher.launch.mainclass", mainClassName);
|
||||
// unit separator ('\u001F') delimited list of game args
|
||||
System.setProperty("org.prismlauncher.launch.gameargs", joinedGameArgs.toString());
|
||||
|
||||
// find and invoke the main method
|
||||
MethodHandle method = ReflectionUtils.findMainMethod(mainClassName);
|
||||
method.invokeExact(gameArgs.toArray(new String[0]));
|
||||
|
@ -1,9 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(qdcss)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 5)
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
find_package(Qt6 COMPONENTS Core Core5Compat REQUIRED)
|
||||
list(APPEND qdcss_LIBS Qt${QT_VERSION_MAJOR}::Core5Compat)
|
||||
endif()
|
||||
|
@ -1,9 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(rainbow)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 5)
|
||||
find_package(Qt5 COMPONENTS Core Gui REQUIRED)
|
||||
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
find_package(Qt6 COMPONENTS Core Gui REQUIRED)
|
||||
endif()
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
project(systeminfo)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 5)
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
if(Launcher_QT_VERSION_MAJOR EQUAL 6)
|
||||
find_package(Qt6 COMPONENTS Core Core5Compat REQUIRED)
|
||||
list(APPEND systeminfo_LIBS Qt${QT_VERSION_MAJOR}::Core5Compat)
|
||||
endif()
|
||||
|
@ -145,11 +145,7 @@ void Sys::lsb_postprocess(Sys::LsbInfo& lsb, Sys::DistributionInfo& out)
|
||||
vers = lsb.codename;
|
||||
} else {
|
||||
// ubuntu, debian, gentoo, scientific, slackware, ... ?
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
auto parts = dist.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts);
|
||||
#else
|
||||
auto parts = dist.split(QRegularExpression("\\s+"), QString::SkipEmptyParts);
|
||||
#endif
|
||||
if (parts.size()) {
|
||||
dist = parts[0];
|
||||
}
|
||||
@ -182,11 +178,7 @@ QString Sys::_extract_distribution(const QString& x)
|
||||
if (release.startsWith("suse linux enterprise")) {
|
||||
return "sles";
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList list = release.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList list = release.split(QRegularExpression("\\s+"), QString::SkipEmptyParts);
|
||||
#endif
|
||||
if (list.size()) {
|
||||
return list[0];
|
||||
}
|
||||
@ -196,11 +188,7 @@ QString Sys::_extract_distribution(const QString& x)
|
||||
QString Sys::_extract_version(const QString& x)
|
||||
{
|
||||
QRegularExpression versionish_string(QRegularExpression::anchoredPattern("\\d+(?:\\.\\d+)*$"));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QStringList list = x.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts);
|
||||
#else
|
||||
QStringList list = x.split(QRegularExpression("\\s+"), QString::SkipEmptyParts);
|
||||
#endif
|
||||
for (int i = list.size() - 1; i >= 0; --i) {
|
||||
QString chunk = list[i];
|
||||
if (versionish_string.match(chunk).hasMatch()) {
|
||||
|
@ -98,9 +98,6 @@ stdenv.mkDerivation {
|
||||
++ lib.optionals (msaClientID != null) [
|
||||
(lib.cmakeFeature "Launcher_MSA_CLIENT_ID" (toString msaClientID))
|
||||
]
|
||||
++ lib.optionals (lib.versionOlder kdePackages.qtbase.version "6") [
|
||||
(lib.cmakeFeature "Launcher_QT_VERSION_MAJOR" "5")
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
# we wrap our binary manually
|
||||
(lib.cmakeFeature "INSTALL_BUNDLE" "nodeps")
|
||||
|
Loading…
x
Reference in New Issue
Block a user