From 909df74f43b43cbdbcbc9a201ee16314072a6847 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 2 Aug 2022 17:10:38 -0400 Subject: [PATCH 01/79] Add sparkle updat push to CI --- .github/workflows/1.build_release.yml | 45 ++++++++++++++++++++++++ .github/workflows/2.nightly_release.yml | 46 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 3ce5a9b02..98a68340a 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -73,3 +73,48 @@ jobs: output/PlayCover_${{ env.TAG_NAME }}.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + + bump-sparkle: + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + repository: Playcover/playcover-website + ref: gh-pages # let me know if i should push to another branch + + - name: Download Artifact + uses: actions/download-artifact@v3.0.0 + with: + path: ./updates/ + + - name: Download Sparkle Toolset + run: | + mkdir sparkle + curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz + tar -xf sparkle.tar.xz -C sparkle + + - name: Update appcast.xml + run: | + echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --ed-key-file - + + - name: Cleanup tmp files + run: | + rm -rf sparkle/ + rm sparkle.tar.xz + + - name: Commit changes + run: | + git add . + git config --local user.email "$GITHUB_EMAIL" + git config --local user.name "$GITHUB_USERNAME" + git commit -m "chore: push update to sparkle" -a + env: + GITHUB_USERNAME: github-actions[bot] + GITHUB_EMAIL: actions@github.com + + - name: Push changes on Website + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.WEBSITE_PAT }} + branch: gh-pages # let me know if i should push to another branch \ No newline at end of file diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index f8646705b..6a8561aac 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -58,3 +58,49 @@ jobs: with: name: PlayCover_nightly_${{ github.run_number }}.dmg path: output/PlayCover_nightly_${{ github.run_number }}.dmg + + +bump-sparkle: + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + repository: Playcover/playcover-website + ref: gh-pages # let me know if i should push to another branch + + - name: Download Artifact + uses: actions/download-artifact@v3.0.0 + with: + path: ./updates/ + + - name: Download Sparkle Toolset + run: | + mkdir sparkle + curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz + tar -xf sparkle.tar.xz -C sparkle + + - name: Update appcast.xml + run: | + echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --channel nightly --ed-key-file - + + - name: Cleanup tmp files + run: | + rm -rf sparkle/ + rm sparkle.tar.xz + + - name: Commit changes + run: | + git add . + git config --local user.email "$GITHUB_EMAIL" + git config --local user.name "$GITHUB_USERNAME" + git commit -m "chore: push update to sparkle" -a + env: + GITHUB_USERNAME: github-actions[bot] + GITHUB_EMAIL: actions@github.com + + - name: Push changes on Website + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.WEBSITE_PAT }} + branch: gh-pages # let me know if i should push to another branch \ No newline at end of file From f1caffe4014e55f96b4f7908d1713f4d59a8ddb1 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 2 Aug 2022 17:25:42 -0400 Subject: [PATCH 02/79] add workflow_dispatch to the build actions --- .github/workflows/1.build_release.yml | 5 ++++- .github/workflows/2.nightly_release.yml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 98a68340a..519c02d67 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -3,6 +3,9 @@ on: push: tags: - "*" + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + env: CI: true jobs: @@ -117,4 +120,4 @@ jobs: uses: ad-m/github-push-action@master with: github_token: ${{ secrets.WEBSITE_PAT }} - branch: gh-pages # let me know if i should push to another branch \ No newline at end of file + branch: gh-pages # let me know if i should push to another branch diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 6a8561aac..623686fea 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -2,6 +2,9 @@ name: Build nightly release on: schedule: - cron: "30 19 * * *" + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + env: CI: true jobs: @@ -103,4 +106,4 @@ bump-sparkle: uses: ad-m/github-push-action@master with: github_token: ${{ secrets.WEBSITE_PAT }} - branch: gh-pages # let me know if i should push to another branch \ No newline at end of file + branch: gh-pages # let me know if i should push to another branch From 645eab250edeb5b44a4cbd446b15bb5c44c1e04d Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Tue, 2 Aug 2022 17:26:51 -0400 Subject: [PATCH 03/79] fix: wait until build job is done to start sparkle job --- .github/workflows/1.build_release.yml | 1 + .github/workflows/2.nightly_release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 519c02d67..8d98e2914 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -78,6 +78,7 @@ jobs: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} bump-sparkle: + needs: build runs-on: macos-latest steps: - name: Checkout diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 623686fea..9516af20b 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -64,6 +64,7 @@ jobs: bump-sparkle: + needs: build runs-on: macos-latest steps: - name: Checkout From 5882807b4e4d40e7fe0d4134799422fa678625a3 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Tue, 9 Aug 2022 21:16:43 -0400 Subject: [PATCH 04/79] fix: invalid yaml structure --- .github/workflows/1.build_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 8d98e2914..08b1b169a 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -104,8 +104,8 @@ jobs: - name: Cleanup tmp files run: | - rm -rf sparkle/ - rm sparkle.tar.xz + rm -rf sparkle/ + rm sparkle.tar.xz - name: Commit changes run: | From d6c37265cd51827c676db30c6ee585855b3cd602 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Tue, 9 Aug 2022 21:18:29 -0400 Subject: [PATCH 05/79] fix: invalid yaml structure --- .github/workflows/2.nightly_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 9516af20b..92300da6d 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -90,8 +90,8 @@ bump-sparkle: - name: Cleanup tmp files run: | - rm -rf sparkle/ - rm sparkle.tar.xz + rm -rf sparkle/ + rm sparkle.tar.xz - name: Commit changes run: | From d16fddbe691d9161796be8c6752b954cb4d10651 Mon Sep 17 00:00:00 2001 From: lucas lee Date: Thu, 4 Aug 2022 15:16:31 +0900 Subject: [PATCH 06/79] load config from .config --- .../AppInstaller/Utils/Entitlements.swift | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/PlayCover/AppInstaller/Utils/Entitlements.swift b/PlayCover/AppInstaller/Utils/Entitlements.swift index a3852eb34..27847f8ab 100644 --- a/PlayCover/AppInstaller/Utils/Entitlements.swift +++ b/PlayCover/AppInstaller/Utils/Entitlements.swift @@ -154,8 +154,13 @@ class Entitlements { """ public static func getDefaultRules() throws -> PlayRules { - guard let path = Bundle.main.path(forResource: "default", ofType: "yaml") else { - throw "Resource not found: default.yaml" + var path : String + if FileManager.default.fileExists(atPath: "~/.config/PlayCover/default.yaml") { + path = "~/.config/PlayCover/default.yaml" + } else if let bpath = Bundle.main.path(forResource: "default", ofType: "yaml") { + path = bpath + } else { + throw "Default config not found: default.yaml" } do { @@ -164,13 +169,18 @@ class Entitlements { let decoded: PlayRules = try decoder.decode(PlayRules.self, from: data) return decoded } catch { - print("failed to get default rules: \(error)") - throw error + print("failed to get default rules at \(path): \(error)") + throw "failed to get default rules at \(path): \(error)" } } public static func getBundleRules(_ bundleID: String) throws -> PlayRules? { - guard let path = Bundle.main.path(forResource: bundleID, ofType: "yaml") else { + var path : String + if FileManager.default.fileExists(atPath: "~/.config/PlayCover/\(bundleID).yaml") { + path = "~/.config/PlayCover/\(bundleID).yaml" + } else if let bpath = Bundle.main.path(forResource: bundleID, ofType: "yaml") { + path = bpath + } else { return nil } @@ -180,7 +190,7 @@ class Entitlements { let decoded: PlayRules = try decoder.decode(PlayRules.self, from: data) return decoded } catch { - print("failed to get bundle rules: \(error)") + print("failed to get bundle rules at \(path): \(error)") throw error } } From d7896f2d9be773a8f9e0de2fadab8b89a4e19699 Mon Sep 17 00:00:00 2001 From: lucus lee Date: Mon, 15 Aug 2022 23:35:47 +0900 Subject: [PATCH 07/79] fix swift lint --- PlayCover/AppInstaller/Utils/Entitlements.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlayCover/AppInstaller/Utils/Entitlements.swift b/PlayCover/AppInstaller/Utils/Entitlements.swift index 27847f8ab..ba5399617 100644 --- a/PlayCover/AppInstaller/Utils/Entitlements.swift +++ b/PlayCover/AppInstaller/Utils/Entitlements.swift @@ -154,7 +154,7 @@ class Entitlements { """ public static func getDefaultRules() throws -> PlayRules { - var path : String + var path: String if FileManager.default.fileExists(atPath: "~/.config/PlayCover/default.yaml") { path = "~/.config/PlayCover/default.yaml" } else if let bpath = Bundle.main.path(forResource: "default", ofType: "yaml") { From a9f9cb2c9766416fac8c720335701ef88392c706 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> Date: Mon, 15 Aug 2022 17:20:04 +0100 Subject: [PATCH 08/79] Better clear app preferences error checking --- PlayCover/AppInstaller/Utils/Entitlements.swift | 2 +- PlayCover/Utils/DeletePreferences.swift | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/PlayCover/AppInstaller/Utils/Entitlements.swift b/PlayCover/AppInstaller/Utils/Entitlements.swift index ba5399617..5f27f38ff 100644 --- a/PlayCover/AppInstaller/Utils/Entitlements.swift +++ b/PlayCover/AppInstaller/Utils/Entitlements.swift @@ -175,7 +175,7 @@ class Entitlements { } public static func getBundleRules(_ bundleID: String) throws -> PlayRules? { - var path : String + var path: String if FileManager.default.fileExists(atPath: "~/.config/PlayCover/\(bundleID).yaml") { path = "~/.config/PlayCover/\(bundleID).yaml" } else if let bpath = Bundle.main.path(forResource: bundleID, ofType: "yaml") { diff --git a/PlayCover/Utils/DeletePreferences.swift b/PlayCover/Utils/DeletePreferences.swift index 81eaf0aca..f8b314f4e 100644 --- a/PlayCover/Utils/DeletePreferences.swift +++ b/PlayCover/Utils/DeletePreferences.swift @@ -10,9 +10,12 @@ import Foundation func deletePreferences(app: String) { let plist = "/Users/\(NSUserName())/Library/Containers/\(app)/Data/Library/Preferences/\(app).plist" let fileManager = FileManager.default + + guard fileManager.fileExists(atPath: plist) else { return } + do { try fileManager.removeItem(atPath: plist) } catch { - Log.shared.error("Error removing preferences: \(error)") + Log.shared.log("\(error)", isError: true) } } From 7df03b50fc20aa3bf80f8dd94c7b58bfbf2a651f Mon Sep 17 00:00:00 2001 From: lucas lee Date: Tue, 16 Aug 2022 20:16:12 +0900 Subject: [PATCH 09/79] improve appcast --- .github/workflows/1.build_release.yml | 108 +++++++++++++----------- .github/workflows/2.nightly_release.yml | 92 ++++++++++---------- 2 files changed, 104 insertions(+), 96 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 08b1b169a..aa4c65599 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -8,12 +8,16 @@ on: env: CI: true + LINK_PREFIX: https://github.com/PlayCover/PlayCover/releases/tag/ + RELEASE_NOTE_PREFIX: https://github.com/PlayCover/PlayCover/releases/tag/ + DOWNLOAD_PREFIX: https://github.com/PlayCover/PlayCover/releases/download/ + jobs: build: runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get the version id: tag_version @@ -44,14 +48,14 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg + mv ./output/*.dmg ./output/PlayCover.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Notarize DMG shell: bash run: | - fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg + fastlane notarize_dmg package:output/PlayCover.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} @@ -62,8 +66,8 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v3 with: - name: PlayCover_${{ env.TAG_NAME }}.dmg - path: output/PlayCover_${{ env.TAG_NAME }}.dmg + name: PlayCover.dmg + path: output/PlayCover.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} @@ -73,52 +77,56 @@ jobs: with: draft: true files: | - output/PlayCover_${{ env.TAG_NAME }}.dmg + output/PlayCover.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + outputs: + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} bump-sparkle: - needs: build - runs-on: macos-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - repository: Playcover/playcover-website - ref: gh-pages # let me know if i should push to another branch - - - name: Download Artifact - uses: actions/download-artifact@v3.0.0 - with: - path: ./updates/ - - - name: Download Sparkle Toolset - run: | - mkdir sparkle - curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz - tar -xf sparkle.tar.xz -C sparkle - - - name: Update appcast.xml - run: | - echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --ed-key-file - - - - name: Cleanup tmp files - run: | - rm -rf sparkle/ - rm sparkle.tar.xz - - - name: Commit changes - run: | - git add . - git config --local user.email "$GITHUB_EMAIL" - git config --local user.name "$GITHUB_USERNAME" - git commit -m "chore: push update to sparkle" -a - env: - GITHUB_USERNAME: github-actions[bot] - GITHUB_EMAIL: actions@github.com - - - name: Push changes on Website - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.WEBSITE_PAT }} - branch: gh-pages # let me know if i should push to another branch + needs: build + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: update # let me know if i should push to another branch + + - name: Download Artifact + uses: actions/download-artifact@v3.0.0 + with: + path: ./updates/ + + - name: Download Sparkle Toolset + run: | + mkdir sparkle + curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz + tar -xf sparkle.tar.xz -C sparkle + + - name: Update appcast.xml + run: | + echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast --channel stable \ + --download-url-prefix 'https://github.com/PlayCover/PlayCover/releases/download/${{ env.TAG_NAME }}/' \ + --link 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ + --full-release-notes-url 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ + -o appcast.xml \ + ./updates --ed-key-file - + env: + TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} + + - name: Cleanup tmp files + run: | + rm -rf sparkle/ + rm sparkle.tar.xz + + - name: Commit changes + run: | + git add appcast.xml + git config --local user.email "$GITHUB_EMAIL" + git config --local user.name "$GITHUB_USERNAME" + git commit -m "chore: add release ${{ env.TAG_NAME }}" -a + git push + env: + GITHUB_USERNAME: github-actions[bot] + GITHUB_EMAIL: actions@github.com + TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 92300da6d..b2e5a0429 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -62,49 +62,49 @@ jobs: name: PlayCover_nightly_${{ github.run_number }}.dmg path: output/PlayCover_nightly_${{ github.run_number }}.dmg - -bump-sparkle: - needs: build - runs-on: macos-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - repository: Playcover/playcover-website - ref: gh-pages # let me know if i should push to another branch - - - name: Download Artifact - uses: actions/download-artifact@v3.0.0 - with: - path: ./updates/ - - - name: Download Sparkle Toolset - run: | - mkdir sparkle - curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz - tar -xf sparkle.tar.xz -C sparkle - - - name: Update appcast.xml - run: | - echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --channel nightly --ed-key-file - - - - name: Cleanup tmp files - run: | - rm -rf sparkle/ - rm sparkle.tar.xz - - - name: Commit changes - run: | - git add . - git config --local user.email "$GITHUB_EMAIL" - git config --local user.name "$GITHUB_USERNAME" - git commit -m "chore: push update to sparkle" -a - env: - GITHUB_USERNAME: github-actions[bot] - GITHUB_EMAIL: actions@github.com - - - name: Push changes on Website - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.WEBSITE_PAT }} - branch: gh-pages # let me know if i should push to another branch + # TODO: Remove the enclosure tag for nightly build. Instead, use the link tag to direct users to download from the GitHub Actions workflow. + # bump-sparkle: + # needs: build + # runs-on: macos-latest + # steps: + # - name: Checkout + # uses: actions/checkout@v2 + # with: + # repository: Playcover/playcover-website + # ref: gh-pages # let me know if i should push to another branch + + # - name: Download Artifact + # uses: actions/download-artifact@v3.0.0 + # with: + # path: ./updates/ + + # - name: Download Sparkle Toolset + # run: | + # mkdir sparkle + # curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz + # tar -xf sparkle.tar.xz -C sparkle + + # - name: Update appcast.xml + # run: | + # echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --channel nightly --ed-key-file - + + # - name: Cleanup tmp files + # run: | + # rm -rf sparkle/ + # rm sparkle.tar.xz + + # - name: Commit changes + # run: | + # git add . + # git config --local user.email "$GITHUB_EMAIL" + # git config --local user.name "$GITHUB_USERNAME" + # git commit -m "chore: push update to sparkle" -a + # env: + # GITHUB_USERNAME: github-actions[bot] + # GITHUB_EMAIL: actions@github.com + + # - name: Push changes on Website + # uses: ad-m/github-push-action@master + # with: + # github_token: ${{ secrets.WEBSITE_PAT }} + # branch: gh-pages # let me know if i should push to another branch From 9cac535c850647275fef3d476bdaf725fb43139c Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 17 Aug 2022 18:59:32 +0900 Subject: [PATCH 10/79] update updater setting --- PlayCover/Info.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PlayCover/Info.plist b/PlayCover/Info.plist index fda1c8cb0..9fedb49fc 100644 --- a/PlayCover/Info.plist +++ b/PlayCover/Info.plist @@ -81,9 +81,9 @@ NSSystemAdministrationUsageDescription PlayCover needs to read files to save apps SUFeedURL - https://playcover.io/updates/appcast.xml + https://raw.githubusercontent.com/PlayCover/PlayCover/master/appcast.xml SUPublicEDKey - u08aYwJaZ3F/qAs2NauIA5DGKhS4nRDccvBDNW8sbi4= + YzgQIwegeMGJxhosWRn/1IyEeEe385xcKE3cXeewlK0= UTExportedTypeDeclarations From c6369d1922642be0e364e523ad6a61f180c9fb72 Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 17 Aug 2022 19:02:56 +0900 Subject: [PATCH 11/79] disable CI for appcast --- .github/workflows/1.build_release.yml | 110 +++++++++++------------- .github/workflows/2.nightly_release.yml | 2 +- 2 files changed, 49 insertions(+), 63 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index aa4c65599..3aa79d8bc 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -3,14 +3,9 @@ on: push: tags: - "*" - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: env: CI: true - LINK_PREFIX: https://github.com/PlayCover/PlayCover/releases/tag/ - RELEASE_NOTE_PREFIX: https://github.com/PlayCover/PlayCover/releases/tag/ - DOWNLOAD_PREFIX: https://github.com/PlayCover/PlayCover/releases/download/ jobs: build: @@ -49,15 +44,11 @@ jobs: run: | create-dmg ./output/PlayCover.app ./output mv ./output/*.dmg ./output/PlayCover.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Notarize DMG shell: bash run: | fastlane notarize_dmg package:output/PlayCover.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Clean Up shell: bash @@ -68,8 +59,6 @@ jobs: with: name: PlayCover.dmg path: output/PlayCover.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Release if: startsWith(github.ref, 'refs/tags/') @@ -78,55 +67,52 @@ jobs: draft: true files: | output/PlayCover.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - outputs: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - bump-sparkle: - needs: build - runs-on: macos-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: update # let me know if i should push to another branch - - - name: Download Artifact - uses: actions/download-artifact@v3.0.0 - with: - path: ./updates/ - - - name: Download Sparkle Toolset - run: | - mkdir sparkle - curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz - tar -xf sparkle.tar.xz -C sparkle - - - name: Update appcast.xml - run: | - echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast --channel stable \ - --download-url-prefix 'https://github.com/PlayCover/PlayCover/releases/download/${{ env.TAG_NAME }}/' \ - --link 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ - --full-release-notes-url 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ - -o appcast.xml \ - ./updates --ed-key-file - - env: - TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} - - - name: Cleanup tmp files - run: | - rm -rf sparkle/ - rm sparkle.tar.xz - - - name: Commit changes - run: | - git add appcast.xml - git config --local user.email "$GITHUB_EMAIL" - git config --local user.name "$GITHUB_USERNAME" - git commit -m "chore: add release ${{ env.TAG_NAME }}" -a - git push - env: - GITHUB_USERNAME: github-actions[bot] - GITHUB_EMAIL: actions@github.com - TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} + # manual release + # bump-sparkle: + # needs: build + # runs-on: macos-latest + # steps: + # - name: Checkout + # uses: actions/checkout@v3 + # with: + # ref: update # let me know if i should push to another branch + + # - name: Download Artifact + # uses: actions/download-artifact@v3.0.0 + # with: + # path: ./updates/ + + # - name: Download Sparkle Toolset + # run: | + # mkdir sparkle + # curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz + # tar -xf sparkle.tar.xz -C sparkle + + # - name: Update appcast.xml + # run: | + # echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast --channel stable \ + # --download-url-prefix 'https://github.com/PlayCover/PlayCover/releases/download/${{ env.TAG_NAME }}/' \ + # --link 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ + # --full-release-notes-url 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ + # -o appcast.xml \ + # ./updates --ed-key-file - + # env: + # TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} + + # - name: Cleanup tmp files + # run: | + # rm -rf sparkle/ + # rm sparkle.tar.xz + + # - name: Commit changes + # run: | + # git add appcast.xml + # git config --local user.email "$GITHUB_EMAIL" + # git config --local user.name "$GITHUB_USERNAME" + # git commit -m "chore: add release ${{ env.TAG_NAME }}" -a + # git push + # env: + # GITHUB_USERNAME: github-actions[bot] + # GITHUB_EMAIL: actions@github.com + # TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index b2e5a0429..d3b55b68f 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -62,7 +62,7 @@ jobs: name: PlayCover_nightly_${{ github.run_number }}.dmg path: output/PlayCover_nightly_${{ github.run_number }}.dmg - # TODO: Remove the enclosure tag for nightly build. Instead, use the link tag to direct users to download from the GitHub Actions workflow. + # manual release # bump-sparkle: # needs: build # runs-on: macos-latest From a7f4a23a8fe69231417e8d01d53291b1808722b8 Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 17 Aug 2022 19:04:38 +0900 Subject: [PATCH 12/79] correct appcast url --- PlayCover/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlayCover/Info.plist b/PlayCover/Info.plist index 9fedb49fc..ad72670bd 100644 --- a/PlayCover/Info.plist +++ b/PlayCover/Info.plist @@ -81,7 +81,7 @@ NSSystemAdministrationUsageDescription PlayCover needs to read files to save apps SUFeedURL - https://raw.githubusercontent.com/PlayCover/PlayCover/master/appcast.xml + https://raw.githubusercontent.com/PlayCover/PlayCover/update/appcast.xml SUPublicEDKey YzgQIwegeMGJxhosWRn/1IyEeEe385xcKE3cXeewlK0= UTExportedTypeDeclarations From 0d449c0c7ce83385a8206b502cd5dd87999e4d8d Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Wed, 17 Aug 2022 11:07:19 -0400 Subject: [PATCH 13/79] remove nightly update channel --- PlayCover/View/Settings/UpdateSettings.swift | 5 ----- PlayCover/View/Sparkle.swift | 17 +---------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/PlayCover/View/Settings/UpdateSettings.swift b/PlayCover/View/Settings/UpdateSettings.swift index cbe32682d..06c1d93f6 100644 --- a/PlayCover/View/Settings/UpdateSettings.swift +++ b/PlayCover/View/Settings/UpdateSettings.swift @@ -11,12 +11,10 @@ import Sparkle struct UpdateSettings: View { @ObservedObject var updaterViewModel: UpdaterViewModel @AppStorage("SUEnableAutomaticChecks") var autoUpdate = false - @AppStorage("nightlyUpdates") var nightlyUpdates = false var body: some View { Form { Toggle("Automatically check for updates", isOn: $autoUpdate) - Toggle("Check for nightly updates", isOn: $nightlyUpdates) Button("Check for updates now…") { updaterViewModel.checkForUpdates() } @@ -26,8 +24,5 @@ struct UpdateSettings: View { .onChange(of: autoUpdate) { value in updaterViewModel.automaticallyCheckForUpdates = value } - .onChange(of: nightlyUpdates) { _ in - updaterViewModel.toggleAllowedChannels() - } } } diff --git a/PlayCover/View/Sparkle.swift b/PlayCover/View/Sparkle.swift index f53f9e644..04fefe83c 100644 --- a/PlayCover/View/Sparkle.swift +++ b/PlayCover/View/Sparkle.swift @@ -12,7 +12,6 @@ import Sparkle // This view model class manages Sparkle's updater and publishes when new updates are allowed to be checked final class UpdaterViewModel: ObservableObject { private let updaterController: SPUStandardUpdaterController - private let updateDelegate = UpdaterDelegate() @Published var canCheckForUpdates = false @@ -29,7 +28,7 @@ final class UpdaterViewModel: ObservableObject { // If you want to start the updater manually, pass false to startingUpdater and call .startUpdater() later // This is where you can also pass an updater delegate if you need one updaterController = SPUStandardUpdaterController(startingUpdater: true, - updaterDelegate: updateDelegate, userDriverDelegate: nil) + updaterDelegate: nil, userDriverDelegate: nil) updaterController.updater.publisher(for: \.canCheckForUpdates) .assign(to: &$canCheckForUpdates) @@ -42,11 +41,6 @@ final class UpdaterViewModel: ObservableObject { func checkForUpdates() { updaterController.checkForUpdates(nil) } - - @discardableResult - func toggleAllowedChannels() -> Set { - return updateDelegate.allowedChannels(for: updaterController.updater) - } } // This additional view is needed for the disabled state on the menu item to work properly before Monterey. @@ -59,12 +53,3 @@ struct CheckForUpdatesView: View { .disabled(!updaterViewModel.canCheckForUpdates) } } - -class UpdaterDelegate: NSObject, SPUUpdaterDelegate { - @AppStorage("nightlyUpdates")var nightlyUpdates = false - - func allowedChannels(for updater: SPUUpdater) -> Set { - let allowedChannels = Set(nightlyUpdates ? ["nightly"] : []) - return allowedChannels - } -} From 519e8ba20e739c64ab28a6cffb791d564435616c Mon Sep 17 00:00:00 2001 From: lucas lee Date: Thu, 18 Aug 2022 00:12:06 +0900 Subject: [PATCH 14/79] fix user customized config --- PlayCover/AppInstaller/Utils/Entitlements.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PlayCover/AppInstaller/Utils/Entitlements.swift b/PlayCover/AppInstaller/Utils/Entitlements.swift index 5f27f38ff..ad7976fbe 100644 --- a/PlayCover/AppInstaller/Utils/Entitlements.swift +++ b/PlayCover/AppInstaller/Utils/Entitlements.swift @@ -155,8 +155,8 @@ class Entitlements { public static func getDefaultRules() throws -> PlayRules { var path: String - if FileManager.default.fileExists(atPath: "~/.config/PlayCover/default.yaml") { - path = "~/.config/PlayCover/default.yaml" + if FileManager.default.fileExists(atPath: "/Users/\(NSUserName())/.config/PlayCover/default.yaml") { + path = "/Users/\(NSUserName())/.config/PlayCover/default.yaml" } else if let bpath = Bundle.main.path(forResource: "default", ofType: "yaml") { path = bpath } else { @@ -176,8 +176,8 @@ class Entitlements { public static func getBundleRules(_ bundleID: String) throws -> PlayRules? { var path: String - if FileManager.default.fileExists(atPath: "~/.config/PlayCover/\(bundleID).yaml") { - path = "~/.config/PlayCover/\(bundleID).yaml" + if FileManager.default.fileExists(atPath: "/Users/\(NSUserName())/.config/PlayCover/\(bundleID).yaml") { + path = "/Users/\(NSUserName())/.config/PlayCover/\(bundleID).yaml" } else if let bpath = Bundle.main.path(forResource: bundleID, ofType: "yaml") { path = bpath } else { From ce0b82557e760ad383895ec68726a8a1be5f2842 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> Date: Wed, 26 Oct 2022 01:32:39 -0400 Subject: [PATCH 15/79] Update Cartfile --- Cartfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cartfile b/Cartfile index d188467ea..70412f8fe 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "PlayCover/PlayTools" "V2.0.0" \ No newline at end of file +github "PlayCover/PlayTools" From b743d8910ea1c5799e41990427c98c6c490c52ac Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Wed, 18 Jan 2023 22:54:55 -0600 Subject: [PATCH 16/79] PlayTools v2.0.7 --- Cartfile.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index dcb3c5ff0..16eff4a61 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "PlayCover/PlayTools" "v2.0.6" +github "PlayCover/PlayTools" "v2.0.7" From c79ae703f95d83a814ecea2dac57cf730a1148c0 Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Mon, 23 Jan 2023 15:44:43 -0600 Subject: [PATCH 17/79] Bugfix release 2.0.4 --- PlayCover.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 3cfdcd2a3..d1a751e7a 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -811,7 +811,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 220; + CURRENT_PROJECT_VERSION = 233; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content"; @@ -826,7 +826,7 @@ ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 2.0.3; + MARKETING_VERSION = 2.0.4; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; @@ -914,7 +914,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 220; + CURRENT_PROJECT_VERSION = 233; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content"; @@ -929,7 +929,7 @@ ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 2.0.3; + MARKETING_VERSION = 2.0.4; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; From a1959b49a911018c4df567d5c7cf5cede1e438fe Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 28 Jan 2023 17:18:31 +0100 Subject: [PATCH 18/79] Translations update from Hosted Weblate (#747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ca/ Translation: PlayCover/PlayCover * Translated using Weblate (Russian) Currently translated at 96.2% (206 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Indonesian) Currently translated at 78.9% (169 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 97.1% (208 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 97.1% (208 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 78.9% (169 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Turkish) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (German) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (German) Currently translated at 100.0% (212 of 212 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Spanish) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (Vietnamese) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Vietnamese) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Trần Thanh Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (212 of 212 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: weng weng Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover --------- Co-authored-by: SkyrilHD Co-authored-by: gallegonovato Co-authored-by: Trần Thanh Co-authored-by: weng weng Co-authored-by: Araide --- PlayCover/ca.lproj/Localizable.strings | 7 +++++++ PlayCover/de.lproj/Localizable.strings | 8 +++++++- PlayCover/es.lproj/Localizable.strings | 6 ++++++ PlayCover/fa.lproj/Localizable.strings | 8 +++++++- PlayCover/fr.lproj/Localizable.strings | 6 ++++++ PlayCover/hi.lproj/Localizable.strings | 6 ++++++ PlayCover/id.lproj/Localizable.strings | 6 ++++++ PlayCover/ja.lproj/Localizable.strings | 8 +++++++- PlayCover/ko.lproj/Localizable.strings | 6 ++++++ PlayCover/pt-br.lproj/Localizable.strings | 6 ++++++ PlayCover/ro.lproj/Localizable.strings | 6 ++++++ PlayCover/ru.lproj/Localizable.strings | 18 ++++++++++++------ PlayCover/tr.lproj/Localizable.strings | 6 ++++++ PlayCover/vi.lproj/Localizable.strings | 8 +++++++- PlayCover/zh-Hans.lproj/Localizable.strings | 10 ++++++++-- PlayCover/zh-Hant.lproj/Localizable.strings | 8 +++++++- 16 files changed, 110 insertions(+), 13 deletions(-) diff --git a/PlayCover/ca.lproj/Localizable.strings b/PlayCover/ca.lproj/Localizable.strings index 3180615b5..7e5d56ea4 100644 --- a/PlayCover/ca.lproj/Localizable.strings +++ b/PlayCover/ca.lproj/Localizable.strings @@ -238,3 +238,10 @@ "configSigning.alert.copied" = "Command Copied!"; "configSigning.alert.info" = "Please paste and run the command in Terminal.app. Your Mac will reboot after"; +"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/de.lproj/Localizable.strings b/PlayCover/de.lproj/Localizable.strings index ee8128b57..8eb2de3ba 100644 --- a/PlayCover/de.lproj/Localizable.strings +++ b/PlayCover/de.lproj/Localizable.strings @@ -379,4 +379,10 @@ "alert.differentBundleIdKeymap.text" = "Bist du dir sicher dass du diese Tastaturbelegung importieren willst?"; "settings.toggle.lldb" = "Öffnen mit LLDB"; "settings.toggle.lldbWithTerminal" = "Im Terminal öffnen"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUD nicht verfügbar"; +"error.failedToStripBinary" = "ARM64-Architektur konnte nicht in Fat Binary gefunden werden!"; +"settings.playChain.enable" = "Aktiviere PlayChain (experimental)"; +"settings.playChain.help" = "Aktiviere die PlayChain-Unterstützung für diese Anwendung, sodass Apple Keychain Services (teilweise) verwendet werden kann"; +"settings.playChain.debugging" = "PlayChain Debugging"; +"playapp.noSources.title" = "Keine IPAs installiert"; +"playapp.noSources.subtitle" = "Du hast derzeit keine IPAs installiert. Klicke auf die Schaltfläche unten, um eine zu importieren."; diff --git a/PlayCover/es.lproj/Localizable.strings b/PlayCover/es.lproj/Localizable.strings index 9946d2115..cc290f866 100644 --- a/PlayCover/es.lproj/Localizable.strings +++ b/PlayCover/es.lproj/Localizable.strings @@ -380,3 +380,9 @@ "settings.toggle.lldb" = "Abrir con LLDB"; "settings.toggle.lldbWithTerminal" = "Abrir en terminal"; "settings.unavailable.hud" = "Metal HUD no disponible"; +"error.failedToStripBinary" = "¡No se pudo encontrar el arch ARM64 en binario para multiarquitectura!"; +"settings.playChain.enable" = "Activar PlayChain (experimental)"; +"settings.playChain.help" = "Habilitar la compatibilidad con PlayChain para esta aplicación, lo que le permite utilizar (parcialmente) los servicios de Keychain de Apple»"; +"settings.playChain.debugging" = "Depuración de PlayChain"; +"playapp.noSources.title" = "No hay IPA instalados"; +"playapp.noSources.subtitle" = "Actualmente no tiene ninguna IPA instalada. Haga clic en el botón de abajo para importar uno."; diff --git a/PlayCover/fa.lproj/Localizable.strings b/PlayCover/fa.lproj/Localizable.strings index 75cbcbca6..18538f319 100644 --- a/PlayCover/fa.lproj/Localizable.strings +++ b/PlayCover/fa.lproj/Localizable.strings @@ -220,4 +220,10 @@ "ipaLibrary.download" = "بارگیری"; "alert.differentBundleIdKeymap.message" = "این Keymap برای برنامه‌ای دیگر ساخته شده است."; "settings.text.debugger" = "اشکال‌زدا:"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUD در دسترس نیست"; +"error.failedToStripBinary" = "معماری ARM64 در این پرونده Binary یافت نشد!"; +"settings.playChain.enable" = "فعال‌سازی PlayChain (آزمایشی)"; +"settings.playChain.help" = "فعال‌سازی PlayChain برای این برنامه تا حدودی دسترسی آن را به سرویس‌های Keychain اپل فراهم می‌کند"; +"settings.playChain.debugging" = "اشکال‌زدای PlayChain"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/fr.lproj/Localizable.strings b/PlayCover/fr.lproj/Localizable.strings index 040ac2c1c..3ef568a3a 100644 --- a/PlayCover/fr.lproj/Localizable.strings +++ b/PlayCover/fr.lproj/Localizable.strings @@ -380,3 +380,9 @@ "alert.differentBundleIdKeymap.message" = "Le keymap peut avoir été créé pour une autre application."; "settings.toggle.lldbWithTerminal" = "Ouvrir dans le terminal"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/hi.lproj/Localizable.strings b/PlayCover/hi.lproj/Localizable.strings index 11e281d5a..257458a52 100644 --- a/PlayCover/hi.lproj/Localizable.strings +++ b/PlayCover/hi.lproj/Localizable.strings @@ -213,3 +213,9 @@ "configSigning.alert.copied" = "कमांड कॉपी किया गया!"; "configSigning.alert.info" = "कृपया Terminal.app में कमांड पेस्ट करें और रन करें। आपका मैक बाद में रीबूट होगा"; "settings.unavailable.hud" = "मेटल HUD अनुपलब्ध है"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/id.lproj/Localizable.strings b/PlayCover/id.lproj/Localizable.strings index 702ad5fce..bf1fe6f43 100644 --- a/PlayCover/id.lproj/Localizable.strings +++ b/PlayCover/id.lproj/Localizable.strings @@ -380,3 +380,9 @@ "settings.toggle.lldb" = "Open with LLDB"; "settings.toggle.lldbWithTerminal" = "Open in terminal"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/ja.lproj/Localizable.strings b/PlayCover/ja.lproj/Localizable.strings index 4c1ab94a5..ad01a9d6c 100644 --- a/PlayCover/ja.lproj/Localizable.strings +++ b/PlayCover/ja.lproj/Localizable.strings @@ -379,4 +379,10 @@ "alert.differentBundleIdKeymap.text" = "このキーマップをインポートしてもよろしいですか?"; "settings.toggle.lldb" = "LLDBで開く"; "settings.toggle.lldbWithTerminal" = "ターミナルで開く"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUDは利用できません"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/ko.lproj/Localizable.strings b/PlayCover/ko.lproj/Localizable.strings index 885aa7847..c2440bec8 100644 --- a/PlayCover/ko.lproj/Localizable.strings +++ b/PlayCover/ko.lproj/Localizable.strings @@ -380,3 +380,9 @@ "alert.differentBundleIdKeymap.message" = "이 키매핑은 다른 앱을 위해 만들어졌을수도 있습니다."; "alert.differentBundleIdKeymap.text" = "정말로 이 키매핑을 불러오시겠습니까?"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.debugging" = "PlayChain debugging"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/pt-br.lproj/Localizable.strings b/PlayCover/pt-br.lproj/Localizable.strings index cedfaa79c..b50c3aa55 100644 --- a/PlayCover/pt-br.lproj/Localizable.strings +++ b/PlayCover/pt-br.lproj/Localizable.strings @@ -213,3 +213,9 @@ "alert.differentBundleIdKeymap.message" = "Esse mapeamento de teclas foi criado para outra aplicação."; "alert.differentBundleIdKeymap.text" = "Tem certeza de que deseja importar esse mapeamento?"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/ro.lproj/Localizable.strings b/PlayCover/ro.lproj/Localizable.strings index fe7729698..0f737190a 100644 --- a/PlayCover/ro.lproj/Localizable.strings +++ b/PlayCover/ro.lproj/Localizable.strings @@ -213,3 +213,9 @@ "settings.toggle.lldb" = "Open with LLDB"; "settings.toggle.lldbWithTerminal" = "Open in terminal"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/ru.lproj/Localizable.strings b/PlayCover/ru.lproj/Localizable.strings index 5c0a76cf4..2eaa1ecde 100644 --- a/PlayCover/ru.lproj/Localizable.strings +++ b/PlayCover/ru.lproj/Localizable.strings @@ -374,9 +374,15 @@ "ipaLibrary.version.older" = "Эта версия старше установленной"; "ipaLibrary.version.same" = "Приложение уже установлено"; "ipaLibrary.version.newer" = "Эта версия новее, чем версия, которую вы установили"; -"ipaLibrary.alert.download" = "Are you sure you want to download this version of %@?"; -"alert.differentBundleIdKeymap.text" = "Are you sure you want to import this keymap?"; -"settings.text.debugger" = "Debugger:"; -"settings.toggle.lldb" = "Open with LLDB"; -"settings.toggle.lldbWithTerminal" = "Open in terminal"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"ipaLibrary.alert.download" = "Вы уверены что хотите установить версию %@?"; +"alert.differentBundleIdKeymap.text" = "Вы действительно хотите импортировать этот кеймап?"; +"settings.text.debugger" = "Дебагер:"; +"settings.toggle.lldb" = "Открыть с помощью LLDB"; +"settings.toggle.lldbWithTerminal" = "Открыть в терминале"; +"settings.unavailable.hud" = "Metal HUD недоступен"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/tr.lproj/Localizable.strings b/PlayCover/tr.lproj/Localizable.strings index b08762282..b1d393d23 100644 --- a/PlayCover/tr.lproj/Localizable.strings +++ b/PlayCover/tr.lproj/Localizable.strings @@ -213,3 +213,9 @@ "settings.toggle.lldb" = "LLDB ile aç"; "settings.toggle.lldbWithTerminal" = "Terminal'de aç"; "settings.unavailable.hud" = "Metal HUD unavailable"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.playChain.enable" = "Enable PlayChain (experimental)"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.noSources.title" = "No IPAs Installed"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; diff --git a/PlayCover/vi.lproj/Localizable.strings b/PlayCover/vi.lproj/Localizable.strings index f85048301..c412f0258 100644 --- a/PlayCover/vi.lproj/Localizable.strings +++ b/PlayCover/vi.lproj/Localizable.strings @@ -220,4 +220,10 @@ "alert.differentBundleIdKeymap.message" = "Keymap này có thể đã được tạo cho một ứng dụng khác."; "alert.differentBundleIdKeymap.text" = "Bạn có chắc chắn muốn nhập keymap này không?"; "settings.toggle.lldbWithTerminal" = "Mở trong Terminal"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUD không khả dụng"; +"error.failedToStripBinary" = "Không tìm thấy file chạy cho ARM64 trong ứng dụng này!"; +"settings.playChain.debugging" = "Gỡ lỗi PlayChain"; +"settings.playChain.enable" = "Sử dụng PlayChain (thử nghiệm)"; +"settings.playChain.help" = "Sử dụng PlayChain cho ứng dụng này, cho phép nó sử dụng một phần các dịch vụ Apple Keychain"; +"playapp.noSources.title" = "Chưa có ứng dụng nào"; +"playapp.noSources.subtitle" = "Hiện tại bạn chưa có ứng dụng nào cả. Click bên dưới để nhâp file IPA."; diff --git a/PlayCover/zh-Hans.lproj/Localizable.strings b/PlayCover/zh-Hans.lproj/Localizable.strings index 7fc633e65..e5ac527fc 100644 --- a/PlayCover/zh-Hans.lproj/Localizable.strings +++ b/PlayCover/zh-Hans.lproj/Localizable.strings @@ -371,7 +371,7 @@ "alert.power.subtitle" = "部分应用程序在启用低电量模式后将无法工作。建议将其关闭。"; "ipaLibrary.version.older" = "此版本比您已安装的应用更旧"; "ipaLibrary.version.same" = "应用已安装"; -"ipaLibrary.version.newer" = "此版本比您已安装的应用更新"; +"ipaLibrary.version.newer" = "这个版本比你已安装的版本更高"; "alert.differentBundleIdKeymap.message" = "此键盘映射文件有可能是为其他应用创建的。"; "alert.differentBundleIdKeymap.text" = "您确定您要导入此键盘映射文件吗?"; "settings.text.debugger" = "调试器:"; @@ -379,4 +379,10 @@ "ipaLibrary.alert.download" = "您确定您要下载这个版本的 %@ 吗?"; "ipaLibrary.download" = "下载"; "settings.toggle.lldbWithTerminal" = "在终端里打开"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUD 不可用"; +"error.failedToStripBinary" = "无法在通用二进制文件中检索到 ARM64 架构!"; +"settings.playChain.enable" = "启用 PlayChain (试验阶段)"; +"settings.playChain.help" = "在此应用启用 PlayChain 将使应用(部分)使用 Apple Keychain 服务"; +"settings.playChain.debugging" = "PlayChain 调试"; +"playapp.noSources.title" = "没有已安装的 IPA"; +"playapp.noSources.subtitle" = "当前你没有安装任何 IPA。点击下面的按钮来导入一个。"; diff --git a/PlayCover/zh-Hant.lproj/Localizable.strings b/PlayCover/zh-Hant.lproj/Localizable.strings index a1ffa67aa..19014fe0c 100644 --- a/PlayCover/zh-Hant.lproj/Localizable.strings +++ b/PlayCover/zh-Hant.lproj/Localizable.strings @@ -359,4 +359,10 @@ "settings.text.debugger" = "調試器:"; "settings.toggle.lldb" = "用 LLDB 高性能調試器打開"; "settings.toggle.lldbWithTerminal" = "用終端打開"; -"settings.unavailable.hud" = "Metal HUD unavailable"; +"settings.unavailable.hud" = "Metal HUD 不可用"; +"settings.playChain.debugging" = "PlayChain 調試"; +"error.failedToStripBinary" = "無法在通用二進制文件中檢索到 ARM64 架構!"; +"settings.playChain.enable" = "啟用 PlayChain (試驗階段)"; +"settings.playChain.help" = "在此應用程序啟用 PlayChain 將使應用程式(部分)使用 Apple Keychain 服務"; +"playapp.noSources.title" = "沒有安裝任何 IPA"; +"playapp.noSources.subtitle" = "暫時沒有安裝任何 IPA 文件。按下下面的按鈕來導入一個。"; From 352e4c0ad836e58328ee61a4899ac0ad308b2fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 14 Feb 2023 19:02:50 -0700 Subject: [PATCH 19/79] Adds toggle to fix screen issues with some apps in adaptive mode (#781) * Adding toggle to fix screen issues with some apps in adaptive mode * Fix pre 13.2 test * Adding macOS Version to app plist * Window fix toggle available for any setting up to 13.1 This fixes responsive for certain apps * Remove macOSVersion --- PlayCover/Model/AppSettings.swift | 25 +++++++++++++++++++++++++ PlayCover/Views/AppSettingsView.swift | 5 +++++ PlayCover/en.lproj/Localizable.strings | 2 ++ 3 files changed, 32 insertions(+) diff --git a/PlayCover/Model/AppSettings.swift b/PlayCover/Model/AppSettings.swift index 6f24758ab..2777164ae 100644 --- a/PlayCover/Model/AppSettings.swift +++ b/PlayCover/Model/AppSettings.swift @@ -22,6 +22,31 @@ struct AppSettingsData: Codable { var bypass = false var discordActivity = DiscordActivity() var version = "2.0.0" + var inverseScreenValues = false + var metalHUD = false + + init() {} + + // handle old 2.x settings where PlayChain did not exist yet + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + keymapping = try container.decodeIfPresent(Bool.self, forKey: .keymapping) ?? true + mouseMapping = try container.decodeIfPresent(Bool.self, forKey: .mouseMapping) ?? true + sensitivity = try container.decodeIfPresent(Float.self, forKey: .sensitivity) ?? 50 + disableTimeout = try container.decodeIfPresent(Bool.self, forKey: .disableTimeout) ?? false + iosDeviceModel = try container.decodeIfPresent(String.self, forKey: .iosDeviceModel) ?? "iPad13,8" + windowWidth = try container.decodeIfPresent(Int.self, forKey: .windowWidth) ?? 1920 + windowHeight = try container.decodeIfPresent(Int.self, forKey: .windowHeight) ?? 1080 + resolution = try container.decodeIfPresent(Int.self, forKey: .resolution) ?? 1 + aspectRatio = try container.decodeIfPresent(Int.self, forKey: .aspectRatio) ?? 1 + notch = try container.decodeIfPresent(Bool.self, forKey: .notch) ?? NSScreen.hasNotch() + bypass = try container.decodeIfPresent(Bool.self, forKey: .bypass) ?? false + discordActivity = try container.decodeIfPresent(DiscordActivity.self, + forKey: .discordActivity) ?? DiscordActivity() + version = try container.decodeIfPresent(String.self, forKey: .version) ?? "2.0.0" + inverseScreenValues = try container.decodeIfPresent(Bool.self, forKey: .inverseScreenValues) ?? false + metalHUD = try container.decodeIfPresent(Bool.self, forKey: .metalHUD) ?? false + } } class AppSettings { diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index f55a7f873..3e7c8ab2e 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -268,6 +268,11 @@ struct GraphicsView: View { } } HStack { + if #available(macOS 13.2, *) { + Toggle("settings.toggle.windowExperimentalFix", isOn: $settings.settings.inverseScreenValues) + .help("settings.toggle.windowExperimentalFix.help") + Spacer() + } Toggle("settings.toggle.disableDisplaySleep", isOn: $settings.settings.disableTimeout) .help("settings.toggle.disableDisplaySleep.help") Spacer() diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index c04579982..6564302dd 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -155,6 +155,8 @@ "settings.text.customWidth" = "Width"; "settings.text.detectedResolution" = "Detected Resolution:"; "settings.picker.aspectRatio" = "Aspect ratio:"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; "settings.toggle.disableDisplaySleep" = "Disable display sleep"; "settings.toggle.disableDisplaySleep.help" = "Prevent display from turning off while this app is running"; "settings.noPlayTools" = "PlayTools is not installed in this app"; From 8199124040527331cc624e5e30d266557fb4fc9e Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Tue, 14 Feb 2023 20:07:34 -0600 Subject: [PATCH 20/79] change url scheme to apple-magnifier --- PlayCover/Info.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PlayCover/Info.plist b/PlayCover/Info.plist index ad72670bd..1ab52087f 100644 --- a/PlayCover/Info.plist +++ b/PlayCover/Info.plist @@ -63,10 +63,10 @@ CFBundleTypeRole Editor CFBundleURLName - io.playcover.PlayCover + com.apple.Magnifier CFBundleURLSchemes - playcover + apple-magnifier From 0e6fffebc75e17bd8a62c79e59225855dcd8d672 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:46:03 -0700 Subject: [PATCH 21/79] feat: high resolution warning (#802) --- PlayCover/Views/AppSettingsView.swift | 18 +++++++++++++++++- PlayCover/en.lproj/Localizable.strings | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index 3e7c8ab2e..81225148c 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -172,6 +172,8 @@ struct GraphicsView: View { @State var customWidth = 1920 @State var customHeight = 1080 + @State var showResolutionWarning = false + static var number: NumberFormatter { let formatter = NumberFormatter() formatter.numberStyle = .none @@ -195,6 +197,18 @@ struct GraphicsView: View { } .frame(width: 250) } + HStack { + if showResolutionWarning { + Spacer() + let highResIcon = Image(systemName: "exclamationmark.triangle") + let warning = NSLocalizedString("settings.highResolution", comment: "") + + Text("\(highResIcon) \(warning)") + .font(.caption) + } else { + Spacer() + } + } HStack { Text("settings.picker.adaptiveRes") Spacer() @@ -326,12 +340,14 @@ struct GraphicsView: View { height = customHeight // Adaptive resolution = Off default: - width = 1920 height = 1080 + width = 1920 } settings.settings.windowWidth = width settings.settings.windowHeight = height + + showResolutionWarning = width*height >= 2621440 // Tends to crash when the number of pixels exceeds that } func getWidthFromAspectRatio(_ height: Int) -> Int { diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index 6564302dd..c58c07696 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -160,6 +160,7 @@ "settings.toggle.disableDisplaySleep" = "Disable display sleep"; "settings.toggle.disableDisplaySleep.help" = "Prevent display from turning off while this app is running"; "settings.noPlayTools" = "PlayTools is not installed in this app"; +"settings.highResolution" = "High resolution may cause crashing"; "settings.tab.jbBypass" = "Jailbreak Bypass"; "settings.toggle.jbBypass" = "Enable Jailbreak Bypass (Alpha)"; From 89185357e14cd610668da59aee17aec464781b8b Mon Sep 17 00:00:00 2001 From: OHaiiBuzzle <23693150+ohaiibuzzle@users.noreply.github.com> Date: Thu, 23 Feb 2023 12:37:37 +0700 Subject: [PATCH 22/79] feat: (slightly) more robust uri handler (#538) * feat: (slightly) more robust URI Handler * fix: behavior tweaks * chore: undo Cartfile.resolved changes * fix: use host instead of path for uri parsing * chore: remove print statement * fix: even tighter checks --- Cartfile | 2 +- PlayCover.xcodeproj/project.pbxproj | 4 + PlayCover/Utils/URLHandler.swift | 101 ++++++++++++++++++ PlayCover/Views/MainView.swift | 8 +- PlayCover/Views/PlayCoverApp.swift | 13 +-- .../Views/Settings/IPASourceSettings.swift | 10 ++ .../Views/Sidebar Views/IPALibraryView.swift | 8 ++ 7 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 PlayCover/Utils/URLHandler.swift diff --git a/Cartfile b/Cartfile index 70412f8fe..41d8c74bf 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "PlayCover/PlayTools" +github "PlayCover/PlayTools" "master" diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index d1a751e7a..0851a63f6 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ AA71964D287A35F400623C15 /* com.nexon.bluearchive.yaml in Resources */ = {isa = PBXBuildFile; fileRef = AA71964C287A35F400623C15 /* com.nexon.bluearchive.yaml */; }; AA818CB5287ABEC3000BEE9D /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = AA818CB4287ABEC3000BEE9D /* Yams */; }; AB671B8C28C9C7DB00B7B102 /* SigningSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB671B8B28C9C7DB00B7B102 /* SigningSetupView.swift */; }; + AB6F21EB299B7FA20078ADEC /* URLHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6F21EA299B7FA20078ADEC /* URLHandler.swift */; }; ABED59832887A32F004D782B /* MenuBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABED59822887A32F004D782B /* MenuBarView.swift */; }; B1084E1F28AA80F400E399FA /* AppSettingsVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1084E1E28AA80F400E399FA /* AppSettingsVM.swift */; }; B1419FB628BA82EE000CB69F /* DiscordActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1419FB528BA82EE000CB69F /* DiscordActivity.swift */; }; @@ -176,6 +177,7 @@ AAE8809E287ACE9F00FBB23C /* cp_frameworks.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = cp_frameworks.sh; sourceTree = ""; }; AAE8809F287ACE9F00FBB23C /* bootstrap.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = bootstrap.sh; sourceTree = ""; }; AB671B8B28C9C7DB00B7B102 /* SigningSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningSetupView.swift; sourceTree = ""; }; + AB6F21EA299B7FA20078ADEC /* URLHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLHandler.swift; sourceTree = ""; }; ABED59822887A32F004D782B /* MenuBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuBarView.swift; sourceTree = ""; }; ABF0BA1A285F9ED200FC5259 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = ""; }; B1084E1E28AA80F400E399FA /* AppSettingsVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsVM.swift; sourceTree = ""; }; @@ -326,6 +328,7 @@ B17FD04628C7B0D900B1D4CA /* AssetsExtractor.swift */, B17FD03F28C70C7300B1D4CA /* CoreUI.h */, 6EB4B57328C93E0600630890 /* LegacySettings.swift */, + AB6F21EA299B7FA20078ADEC /* URLHandler.swift */, ); path = Utils; sourceTree = ""; @@ -684,6 +687,7 @@ 28361D5E2892781200B35EDB /* RestoreGenshinUserData.swift in Sources */, 36B26B97288C724600859EFD /* UpdateSettings.swift in Sources */, 8783CFFB26B8C52D00171041 /* PlayCoverApp.swift in Sources */, + AB6F21EB299B7FA20078ADEC /* URLHandler.swift in Sources */, 6ED6379D28DAAAC100B506FA /* IPASourceSettings.swift in Sources */, 5314D1EE26C402EC00A0A727 /* Shell.swift in Sources */, 6E7CA16528B4D02900216CD8 /* ITunesResponse.swift in Sources */, diff --git a/PlayCover/Utils/URLHandler.swift b/PlayCover/Utils/URLHandler.swift new file mode 100644 index 000000000..a185de6a0 --- /dev/null +++ b/PlayCover/Utils/URLHandler.swift @@ -0,0 +1,101 @@ +// +// URIHandler.swift +// PlayCover +// +// Created by Venti on 14/02/2023. +// + +import Foundation + +enum URLTypes: Int, Equatable { + case source + case keymap + case app +} + +enum URLAction: Int, Equatable { + case add + case remove + case update + case install + case open +} + +class URLObservable: ObservableObject { + @Published var url: String? + @Published var type: URLTypes? + @Published var action: URLAction? + + public static var shared = URLObservable() +} + +struct URLHandler { + public static var shared = URLHandler() + + func processURL(url: URL) { + guard let urlComponenents = NSURLComponents(url: url, resolvingAgainstBaseURL: false), + let uriHost = urlComponenents.host, + let params = urlComponenents.queryItems else { + // Fall back to old url handler (for files) + if url.pathExtension == "ipa" { + Installer.install(ipaUrl: url, export: false, returnCompletion: { _ in + Task { @MainActor in + AppsVM.shared.fetchApps() + NotifyService.shared.notify( + NSLocalizedString("notification.appInstalled", comment: ""), + NSLocalizedString("notification.appInstalled.message", comment: "") + ) + }}) + } + return + } + // URI format: playcoverapp://?action=&= + // Example: playcoverapp://source?action=add&url=https://homebrew.playcover.io + // Switch case for main uri path + switch uriHost { + case "source": + processSourceURL(params: params) + default: + // Print URL to log and break + NSLog("Unknown URL: \(url)") + } + } + + func processSourceURL(params: [URLQueryItem]) { + // Make dang sure we have the params we need and they match expected query items + guard params.count == 2, + params[0].name == "action", + params[1].name == "url" else { + // Print params to logs and break + NSLog("Unknown source URL params: \(params)") + return + } + + if let actionParam = params[0].value { + URLObservable.shared.type = .source + switch actionParam { + case "add": + // Add source + if let url = params[1].value { + URLObservable.shared.url = url + URLObservable.shared.action = .add + } + case "remove": + // Remove source + if let url = params[1].value { + URLObservable.shared.url = url + URLObservable.shared.action = .remove + } + case "update": + // Update source + if let url = params[1].value { + URLObservable.shared.url = url + URLObservable.shared.action = .update + } + default: + // Print params to console and break + print("Unknown source URL params: \(params)") + } + } + } +} diff --git a/PlayCover/Views/MainView.swift b/PlayCover/Views/MainView.swift index 4a08ede88..ba79e0d0c 100644 --- a/PlayCover/Views/MainView.swift +++ b/PlayCover/Views/MainView.swift @@ -29,6 +29,9 @@ struct MainView: View { @State private var xcodeInstallStatus: XcodeInstallStatus = .installing @State private var selectedBackgroundColor: Color = Color.accentColor @State private var selectedTextColor: Color = Color.black + + @ObservedObject private var URLObserved = URLObservable.shared + var body: some View { GeometryReader { viewGeom in NavigationView { @@ -88,7 +91,7 @@ struct MainView: View { .background(SplitViewAccessor(sideCollapsed: $collapsed)) } .onAppear { - self.selectedView = 1 + self.selectedView = URLObserved.type == .source ? 2 : 1 } .toolbar { ToolbarItem(placement: .navigation) { @@ -216,6 +219,9 @@ struct MainView: View { .sheet(isPresented: $isSigningSetupShown) { SignSetupView(isSigningSetupShown: $isSigningSetupShown) } + .onChange(of: URLObserved.action) { _ in + self.selectedView = URLObserved.type == .source ? 2 : self.selectedView + } } .frame(minWidth: 675, minHeight: 330) } diff --git a/PlayCover/Views/PlayCoverApp.swift b/PlayCover/Views/PlayCoverApp.swift index 8fed84d05..f36801579 100644 --- a/PlayCover/Views/PlayCoverApp.swift +++ b/PlayCover/Views/PlayCoverApp.swift @@ -8,18 +8,7 @@ import SwiftUI class AppDelegate: NSObject, NSApplicationDelegate { func application(_ application: NSApplication, open urls: [URL]) { if let url = urls.first { - if url.pathExtension == "ipa" { - uif.ipaUrl = url - Installer.install(ipaUrl: uif.ipaUrl!, export: false, returnCompletion: { _ in - Task { @MainActor in - AppsVM.shared.apps = [] - AppsVM.shared.fetchApps() - NotifyService.shared.notify( - NSLocalizedString("notification.appInstalled", comment: ""), - NSLocalizedString("notification.appInstalled.message", comment: "")) - } - }) - } + URLHandler.shared.processURL(url: url) } } diff --git a/PlayCover/Views/Settings/IPASourceSettings.swift b/PlayCover/Views/Settings/IPASourceSettings.swift index 2fd13ed1e..c78ceccd0 100644 --- a/PlayCover/Views/Settings/IPASourceSettings.swift +++ b/PlayCover/Views/Settings/IPASourceSettings.swift @@ -220,6 +220,16 @@ struct AddSourceView: View { .onChange(of: newSource) { source in validateSource(source) } + .onAppear { + if URLObservable.shared.type == .source { + newSource = URLObservable.shared.url ?? "" + } + } + .onDisappear { + URLObservable.shared.url = nil + URLObservable.shared.type = nil + URLObservable.shared.action = nil + } } func validateSource(_ source: String) { diff --git a/PlayCover/Views/Sidebar Views/IPALibraryView.swift b/PlayCover/Views/Sidebar Views/IPALibraryView.swift index d58e13bd8..aea08e447 100644 --- a/PlayCover/Views/Sidebar Views/IPALibraryView.swift +++ b/PlayCover/Views/Sidebar Views/IPALibraryView.swift @@ -19,6 +19,8 @@ struct IPALibraryView: View { @State private var selected: StoreAppData? @State private var addSourcePresented = false + @ObservedObject private var URLObserved = URLObservable.shared + var body: some View { ZStack { ScrollView { @@ -115,5 +117,11 @@ struct IPALibraryView: View { AddSourceView(addSourceSheet: $addSourcePresented) .environmentObject(storeVM) } + .onChange(of: URLObserved.type) {_ in + addSourcePresented = URLObserved.type == .source + } + .onAppear { + addSourcePresented = URLObserved.type == .source + } } } From 38221632b898024a8512ef52d0a840183afd886a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 23 Feb 2023 15:46:04 +0100 Subject: [PATCH 23/79] Translations update from Hosted Weblate (#803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Russian) Currently translated at 86.0% (198 of 230 strings) Translated using Weblate (Russian) Currently translated at 86.4% (198 of 229 strings) Translated using Weblate (Russian) Currently translated at 87.2% (198 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Indonesian) Currently translated at 70.4% (162 of 230 strings) Translated using Weblate (Indonesian) Currently translated at 70.7% (162 of 229 strings) Translated using Weblate (Indonesian) Currently translated at 71.3% (162 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 94.3% (217 of 230 strings) Translated using Weblate (Japanese) Currently translated at 86.9% (200 of 230 strings) Translated using Weblate (Japanese) Currently translated at 87.3% (200 of 229 strings) Translated using Weblate (Japanese) Currently translated at 88.1% (200 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: ささ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 88.2% (203 of 230 strings) Translated using Weblate (Korean) Currently translated at 88.6% (203 of 229 strings) Translated using Weblate (Korean) Currently translated at 89.4% (203 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 88.2% (203 of 230 strings) Translated using Weblate (Persian) Currently translated at 88.6% (203 of 229 strings) Translated using Weblate (Persian) Currently translated at 89.4% (203 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 70.4% (162 of 230 strings) Translated using Weblate (Romanian) Currently translated at 70.7% (162 of 229 strings) Translated using Weblate (Romanian) Currently translated at 71.3% (162 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 230 strings) Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 229 strings) Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ca/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover * Translated using Weblate (Turkish) Currently translated at 89.1% (205 of 230 strings) Translated using Weblate (Turkish) Currently translated at 89.5% (205 of 229 strings) Translated using Weblate (Turkish) Currently translated at 90.3% (205 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 86.9% (200 of 230 strings) Translated using Weblate (Hindi) Currently translated at 87.3% (200 of 229 strings) Translated using Weblate (Hindi) Currently translated at 88.1% (200 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 86.5% (199 of 230 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 86.8% (199 of 229 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 87.6% (199 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Spanish) Currently translated at 99.5% (229 of 230 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (229 of 229 strings) Translated using Weblate (Spanish) Currently translated at 99.1% (227 of 229 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (227 of 227 strings) Translated using Weblate (Spanish) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (German) Currently translated at 99.5% (229 of 230 strings) Translated using Weblate (German) Currently translated at 100.0% (229 of 229 strings) Translated using Weblate (German) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (German) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Vietnamese) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Vietnamese) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Vietnamese) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (French) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (French) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover --------- Co-authored-by: ささ Co-authored-by: Araide Co-authored-by: gallegonovato Co-authored-by: SkyrilHD --- PlayCover/ca.lproj/Localizable.strings | 20 +++++++++++++ PlayCover/de.lproj/Localizable.strings | 17 +++++++++++ PlayCover/es.lproj/Localizable.strings | 17 +++++++++++ PlayCover/fa.lproj/Localizable.strings | 17 +++++++++++ PlayCover/fr.lproj/Localizable.strings | 31 ++++++++++++++++----- PlayCover/hi.lproj/Localizable.strings | 17 +++++++++++ PlayCover/id.lproj/Localizable.strings | 17 +++++++++++ PlayCover/ja.lproj/Localizable.strings | 27 ++++++++++++++++-- PlayCover/ko.lproj/Localizable.strings | 23 +++++++++++++-- PlayCover/pt-br.lproj/Localizable.strings | 17 +++++++++++ PlayCover/ro.lproj/Localizable.strings | 17 +++++++++++ PlayCover/ru.lproj/Localizable.strings | 17 +++++++++++ PlayCover/tr.lproj/Localizable.strings | 31 ++++++++++++++++----- PlayCover/vi.lproj/Localizable.strings | 17 +++++++++++ PlayCover/zh-Hans.lproj/Localizable.strings | 17 +++++++++++ PlayCover/zh-Hant.lproj/Localizable.strings | 17 +++++++++++ 16 files changed, 299 insertions(+), 20 deletions(-) diff --git a/PlayCover/ca.lproj/Localizable.strings b/PlayCover/ca.lproj/Localizable.strings index 7e5d56ea4..b00220b50 100644 --- a/PlayCover/ca.lproj/Localizable.strings +++ b/PlayCover/ca.lproj/Localizable.strings @@ -245,3 +245,23 @@ "settings.playChain.debugging" = "PlayChain debugging"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.downloading" = "Downloading"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.finished" = "Finished"; +"playapp.progress.failed" = "Failed"; +"playapp.progress.canceled" = "Canceled"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"button.Reload" = "Reload"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/de.lproj/Localizable.strings b/PlayCover/de.lproj/Localizable.strings index 8eb2de3ba..d467c10f7 100644 --- a/PlayCover/de.lproj/Localizable.strings +++ b/PlayCover/de.lproj/Localizable.strings @@ -386,3 +386,20 @@ "settings.playChain.debugging" = "PlayChain Debugging"; "playapp.noSources.title" = "Keine IPAs installiert"; "playapp.noSources.subtitle" = "Du hast derzeit keine IPAs installiert. Klicke auf die Schaltfläche unten, um eine zu importieren."; +"settings.tab.bypasses" = "Umgeht"; +"settings.addToLaunchpad" = "Zum Launchpad hinzufügen"; +"settings.removeFromLaunchpad" = "Vom Launchpad entfernen"; +"playapp.download.integrityCheck" = "Überprüfung der Dateiintegrität:"; +"playapp.download.differentChecksum" = "Unterschiedliche Prüfsummen! Möchtest du mit der Installation fortfahren?"; +"playapp.download.differentChecksumDesc" = "\"%@\" erwartet, \"%@\" erhalten"; +"playapp.progress.canceled" = "Abgebrochen"; +"button.Reload" = "Neu laden"; +"playapp.clearPlayChain" = "PlayChain-Daten leeren"; +"playapp.importIPA" = "IPA importieren"; +"ipaLibrary.noNetworkConnection.required" = "IPA-Bibliothek erfordert eine Internetverbindung"; +"preferences.toggle.removePlayChain" = "PlayChain entfernen"; +"preferences.popover.duplicate" = "Link duplizieren"; +"alert.app.clearPlayChain" = "Alle PlayChain-Daten werden gelöscht. Möglicherweise müssen Sie sich erneut bei der App anmelden. Möchten Sie fortfahren?"; +"settings.toggle.windowExperimentalFix.help" = "Versucht, deine App-Szene zu reparieren, wenn du Probleme damit hast"; +"settings.toggle.windowExperimentalFix" = "Fensterprobleme beheben"; +"settings.highResolution" = "Hohe Auflösung kann zu Abstürzen führen"; diff --git a/PlayCover/es.lproj/Localizable.strings b/PlayCover/es.lproj/Localizable.strings index cc290f866..ca748cb51 100644 --- a/PlayCover/es.lproj/Localizable.strings +++ b/PlayCover/es.lproj/Localizable.strings @@ -386,3 +386,20 @@ "settings.playChain.debugging" = "Depuración de PlayChain"; "playapp.noSources.title" = "No hay IPA instalados"; "playapp.noSources.subtitle" = "Actualmente no tiene ninguna IPA instalada. Haga clic en el botón de abajo para importar uno."; +"settings.tab.bypasses" = "Bypass"; +"settings.addToLaunchpad" = "Agregar al Launchpad"; +"settings.removeFromLaunchpad" = "Quitar del Launchpad"; +"playapp.download.integrityCheck" = "Verificar la integridad de los archivos:"; +"playapp.download.differentChecksum" = "¡Diferentes sumas de control! ¿Desea continuar con la instalación?"; +"playapp.download.differentChecksumDesc" = "Esperado \"%@\", obtenido \"%@\""; +"playapp.progress.canceled" = "Cancelado"; +"button.Reload" = "Recargar"; +"playapp.clearPlayChain" = "Borrar los datos de PlayChain"; +"playapp.importIPA" = "Importar IPA"; +"ipaLibrary.noNetworkConnection.required" = "La Biblioteca IPA requiere conexión a Internet"; +"preferences.toggle.removePlayChain" = "Eliminar PlayChain"; +"preferences.popover.duplicate" = "Duplicar enlace"; +"alert.app.clearPlayChain" = "Se borrarán todos los datos de PlayChain. Es posible que tengas que volver a iniciar la sesión en la aplicación. ¿Deseas continuar?"; +"settings.toggle.windowExperimentalFix.help" = "Intenta arreglar la escena de tu aplicación si tienes problemas con ella"; +"settings.toggle.windowExperimentalFix" = "Solucionado los problemas donde la ventana"; +"settings.highResolution" = "La alta resolución puede provocar fallos"; diff --git a/PlayCover/fa.lproj/Localizable.strings b/PlayCover/fa.lproj/Localizable.strings index 18538f319..c4b3bfd28 100644 --- a/PlayCover/fa.lproj/Localizable.strings +++ b/PlayCover/fa.lproj/Localizable.strings @@ -227,3 +227,20 @@ "settings.playChain.debugging" = "اشکال‌زدای PlayChain"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.progress.canceled" = "Canceled"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/fr.lproj/Localizable.strings b/PlayCover/fr.lproj/Localizable.strings index 3ef568a3a..00afa165a 100644 --- a/PlayCover/fr.lproj/Localizable.strings +++ b/PlayCover/fr.lproj/Localizable.strings @@ -379,10 +379,27 @@ "settings.toggle.lldb" = "Ouvrir avec LLDB"; "alert.differentBundleIdKeymap.message" = "Le keymap peut avoir été créé pour une autre application."; "settings.toggle.lldbWithTerminal" = "Ouvrir dans le terminal"; -"settings.unavailable.hud" = "Metal HUD unavailable"; -"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; -"settings.playChain.enable" = "Enable PlayChain (experimental)"; -"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; -"settings.playChain.debugging" = "PlayChain debugging"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.unavailable.hud" = "Metal HUD indisponible"; +"error.failedToStripBinary" = "Impossible de trouver l'architecture ARM64 dans le binaire fat !"; +"settings.playChain.enable" = "Activer PlayChain (Expérimental)"; +"settings.playChain.help" = "Activer la prise en charge de PlayChain pour cette application, lui permettant d'utiliser (partiellement) les services Apple Keychain"; +"settings.playChain.debugging" = "Débogage de PlayChain"; +"playapp.noSources.title" = "Aucun IPA installé"; +"playapp.noSources.subtitle" = "Actuellement, vous n'avez aucun IPA installé. Cliquez sur le bouton ci-dessous pour en importer un."; +"settings.tab.bypasses" = "Contournements"; +"settings.addToLaunchpad" = "Ajouter à Launchpad"; +"settings.removeFromLaunchpad" = "Supprimer de Launchpad"; +"playapp.download.integrityCheck" = "Vérification de l'intégrité des fichiers :"; +"playapp.download.differentChecksum" = "Différentes sommes de contrôle ! Voulez-vous continuer l’installation ?"; +"playapp.download.differentChecksumDesc" = "Attendu \"%@\", obtenu \"%@\""; +"playapp.progress.canceled" = "Annulé"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/hi.lproj/Localizable.strings b/PlayCover/hi.lproj/Localizable.strings index 257458a52..f901e5806 100644 --- a/PlayCover/hi.lproj/Localizable.strings +++ b/PlayCover/hi.lproj/Localizable.strings @@ -219,3 +219,20 @@ "settings.playChain.debugging" = "PlayChain debugging"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.progress.canceled" = "Canceled"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.importIPA" = "Import IPA"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/id.lproj/Localizable.strings b/PlayCover/id.lproj/Localizable.strings index bf1fe6f43..57e22d68c 100644 --- a/PlayCover/id.lproj/Localizable.strings +++ b/PlayCover/id.lproj/Localizable.strings @@ -386,3 +386,20 @@ "error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"playapp.importIPA" = "Import IPA"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/ja.lproj/Localizable.strings b/PlayCover/ja.lproj/Localizable.strings index ad01a9d6c..3ffcc9684 100644 --- a/PlayCover/ja.lproj/Localizable.strings +++ b/PlayCover/ja.lproj/Localizable.strings @@ -107,7 +107,11 @@ "playapp.install.createWrapper" = "アプリのコンテナーを作成中..."; /* (No Comment) */ +<<<<<<< HEAD "playapp.install.finished" = "完成"; +======= +"playapp.progress.finished" = "完了"; +>>>>>>> 5d52ecd (Translations update from Hosted Weblate (#803)) /* (No Comment) */ "playapp.install.installPlayTools" = "PlayToolsをインストール中..."; @@ -380,9 +384,26 @@ "settings.toggle.lldb" = "LLDBで開く"; "settings.toggle.lldbWithTerminal" = "ターミナルで開く"; "settings.unavailable.hud" = "Metal HUDは利用できません"; -"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"error.failedToStripBinary" = "ファット バイナリで ARM64 arch が見つかりませんでした!"; "settings.playChain.enable" = "Enable PlayChain (experimental)"; "settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; "settings.playChain.debugging" = "PlayChain debugging"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"playapp.noSources.title" = "IPA がインストールされていません"; +"playapp.noSources.subtitle" = "現在、IPA はインストールされていません。 下のボタンをクリックしてインポートします。"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.tab.bypasses" = "Bypasses"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.integrityCheck" = "ファイルの整合性の検証中:"; +"playapp.download.differentChecksum" = "チェックサムが異なります! インストールを続行しますか?"; +"playapp.download.differentChecksumDesc" = "期待される \"%@\", got \"%@\""; +"playapp.progress.canceled" = "キャンセルされました"; +"playapp.importIPA" = "ipaをインポート"; +"preferences.toggle.removePlayChain" = "PlayChainを削除"; +"button.Reload" = "リロード"; +"playapp.clearPlayChain" = "PlayChain データを消去"; +"ipaLibrary.noNetworkConnection.required" = "IPAライブラリにはインターネット接続が必要です"; +"preferences.popover.duplicate" = "リンクを複製"; +"alert.app.clearPlayChain" = "すべての PlayChain データが消去されます。 アプリへの再ログインが必要になる場合があります。 続けますか?"; +"settings.toggle.windowExperimentalFix.help" = "問題がある場合は、アプリのシーンを修正しようとします"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/ko.lproj/Localizable.strings b/PlayCover/ko.lproj/Localizable.strings index c2440bec8..656c54e58 100644 --- a/PlayCover/ko.lproj/Localizable.strings +++ b/PlayCover/ko.lproj/Localizable.strings @@ -383,6 +383,23 @@ "error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; "settings.playChain.debugging" = "PlayChain debugging"; "settings.playChain.enable" = "Enable PlayChain (experimental)"; -"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.playChain.help" = "이 애플리케이션에 대한 PlayChain 지원을 활성화하여 Apple 키체인 서비스를 (부분적으로) 사용할 수 있도록 합니다"; +"playapp.noSources.title" = "설치된 IPA가 없음"; +"playapp.noSources.subtitle" = "현재 설치된 IPA가 없습니다. 아래 버튼을 클릭하여 가져오세요."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/pt-br.lproj/Localizable.strings b/PlayCover/pt-br.lproj/Localizable.strings index b50c3aa55..87a89ab6f 100644 --- a/PlayCover/pt-br.lproj/Localizable.strings +++ b/PlayCover/pt-br.lproj/Localizable.strings @@ -219,3 +219,20 @@ "settings.playChain.debugging" = "PlayChain debugging"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"playapp.importIPA" = "Import IPA"; +"button.Reload" = "Reload"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/ro.lproj/Localizable.strings b/PlayCover/ro.lproj/Localizable.strings index 0f737190a..852aa3477 100644 --- a/PlayCover/ro.lproj/Localizable.strings +++ b/PlayCover/ro.lproj/Localizable.strings @@ -219,3 +219,20 @@ "settings.playChain.debugging" = "PlayChain debugging"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.progress.canceled" = "Canceled"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/ru.lproj/Localizable.strings b/PlayCover/ru.lproj/Localizable.strings index 2eaa1ecde..6dab8e191 100644 --- a/PlayCover/ru.lproj/Localizable.strings +++ b/PlayCover/ru.lproj/Localizable.strings @@ -386,3 +386,20 @@ "settings.playChain.debugging" = "PlayChain debugging"; "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"playapp.importIPA" = "Import IPA"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/tr.lproj/Localizable.strings b/PlayCover/tr.lproj/Localizable.strings index b1d393d23..05abbf777 100644 --- a/PlayCover/tr.lproj/Localizable.strings +++ b/PlayCover/tr.lproj/Localizable.strings @@ -212,10 +212,27 @@ "settings.text.debugger" = "Debugger:"; "settings.toggle.lldb" = "LLDB ile aç"; "settings.toggle.lldbWithTerminal" = "Terminal'de aç"; -"settings.unavailable.hud" = "Metal HUD unavailable"; -"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; -"settings.playChain.enable" = "Enable PlayChain (experimental)"; -"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; -"settings.playChain.debugging" = "PlayChain debugging"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.unavailable.hud" = "Metal HUD kullanım dışı"; +"error.failedToStripBinary" = "Fat binary'de ARM64 arch bulunamadı!"; +"settings.playChain.enable" = "PlayChain'i aktive et (deneysel)"; +"settings.playChain.help" = "Bu uygulamanın Apple Keychain Servislerini kullanması için PlayChain desteğini aç"; +"settings.playChain.debugging" = "PlayChain debuglaması"; +"playapp.noSources.title" = "İndirilmiş IPA Yok"; +"playapp.noSources.subtitle" = "İndirilmiş IPA yok. Eklemek için aşağıya tıkla."; +"settings.tab.bypasses" = "Bypasses"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"playapp.importIPA" = "Import IPA"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.popover.duplicate" = "Duplicate Link"; +"button.Reload" = "Reload"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/vi.lproj/Localizable.strings b/PlayCover/vi.lproj/Localizable.strings index c412f0258..d225e14f5 100644 --- a/PlayCover/vi.lproj/Localizable.strings +++ b/PlayCover/vi.lproj/Localizable.strings @@ -227,3 +227,20 @@ "settings.playChain.help" = "Sử dụng PlayChain cho ứng dụng này, cho phép nó sử dụng một phần các dịch vụ Apple Keychain"; "playapp.noSources.title" = "Chưa có ứng dụng nào"; "playapp.noSources.subtitle" = "Hiện tại bạn chưa có ứng dụng nào cả. Click bên dưới để nhâp file IPA."; +"settings.tab.bypasses" = "Bypass"; +"settings.addToLaunchpad" = "Thêm vào Launchpad"; +"settings.removeFromLaunchpad" = "Xóa khỏi Launchpad"; +"playapp.download.integrityCheck" = "Xác minh tính toàn vẹn của tệp:"; +"playapp.download.differentChecksum" = "Checksum khác nhau! Bạn có muốn tiếp tục cài đặt không?"; +"playapp.download.differentChecksumDesc" = "Dự kiến \"%@\", đã xong \"%@\""; +"playapp.progress.canceled" = "Đã hủy"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"button.Reload" = "Reload"; +"playapp.importIPA" = "Import IPA"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"preferences.popover.duplicate" = "Duplicate Link"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"settings.toggle.windowExperimentalFix.help" = "Attempts to fix your app scene if you have problems with it"; +"settings.toggle.windowExperimentalFix" = "Fix window issues"; +"settings.highResolution" = "High resolution may cause crashing"; diff --git a/PlayCover/zh-Hans.lproj/Localizable.strings b/PlayCover/zh-Hans.lproj/Localizable.strings index e5ac527fc..8cb434e25 100644 --- a/PlayCover/zh-Hans.lproj/Localizable.strings +++ b/PlayCover/zh-Hans.lproj/Localizable.strings @@ -386,3 +386,20 @@ "settings.playChain.debugging" = "PlayChain 调试"; "playapp.noSources.title" = "没有已安装的 IPA"; "playapp.noSources.subtitle" = "当前你没有安装任何 IPA。点击下面的按钮来导入一个。"; +"settings.tab.bypasses" = "绕过"; +"settings.addToLaunchpad" = "添加到启动台"; +"settings.removeFromLaunchpad" = "从启动台移除"; +"playapp.download.integrityCheck" = "正在验证文件完整性:"; +"playapp.download.differentChecksum" = "校验不一致!你是否想要继续安装?"; +"playapp.download.differentChecksumDesc" = "预期为 \"%@\", 当前为 \"%@\""; +"playapp.progress.canceled" = "已取消"; +"preferences.toggle.removePlayChain" = "移除 PlayChain"; +"button.Reload" = "刷新"; +"playapp.clearPlayChain" = "清除 PlayChain 数据"; +"playapp.importIPA" = "导入 IPA"; +"ipaLibrary.noNetworkConnection.required" = "连接网络以查看 IPA Library"; +"preferences.popover.duplicate" = "复制链接"; +"alert.app.clearPlayChain" = "所有 PlayChain 数据将被清除。您可能需要重新登录应用程式。您还想继续吗?"; +"settings.toggle.windowExperimentalFix.help" = "尝试修复您的应用程式场景"; +"settings.toggle.windowExperimentalFix" = "修复窗口问题"; +"settings.highResolution" = "高画质可能会导致闪退"; diff --git a/PlayCover/zh-Hant.lproj/Localizable.strings b/PlayCover/zh-Hant.lproj/Localizable.strings index 19014fe0c..851128cee 100644 --- a/PlayCover/zh-Hant.lproj/Localizable.strings +++ b/PlayCover/zh-Hant.lproj/Localizable.strings @@ -366,3 +366,20 @@ "settings.playChain.help" = "在此應用程序啟用 PlayChain 將使應用程式(部分)使用 Apple Keychain 服務"; "playapp.noSources.title" = "沒有安裝任何 IPA"; "playapp.noSources.subtitle" = "暫時沒有安裝任何 IPA 文件。按下下面的按鈕來導入一個。"; +"settings.tab.bypasses" = "Bypasses"; +"settings.removeFromLaunchpad" = "Remove from Launchpad"; +"settings.addToLaunchpad" = "Add to Launchpad"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"playapp.progress.canceled" = "Canceled"; +"playapp.importIPA" = "導入 IPA"; +"preferences.popover.duplicate" = "複製連結"; +"button.Reload" = "刷新"; +"playapp.clearPlayChain" = "清除 PlayChain 數據"; +"ipaLibrary.noNetworkConnection.required" = "連接實際網路以查看 IPA Library"; +"preferences.toggle.removePlayChain" = "移除 PlayChain"; +"alert.app.clearPlayChain" = "所有 PlayChain 數據將被清除。您可能需要重新登錄應用程式。 您還希望繼續嗎?"; +"settings.toggle.windowExperimentalFix.help" = "嘗試修復您的應用程式場景"; +"settings.toggle.windowExperimentalFix" = "修復窗口問題"; +"settings.highResolution" = "高畫質可能會導致閃退"; From e708d9d0571ecb583b922b268d7cb0cfefce15bd Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 10 Feb 2023 06:16:07 -0700 Subject: [PATCH 24/79] fix: deselect app on uninstall (#792) --- PlayCover/Views/App Views/PlayAppView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/PlayCover/Views/App Views/PlayAppView.swift b/PlayCover/Views/App Views/PlayAppView.swift index f2896d78f..90f6b85d1 100644 --- a/PlayCover/Views/App Views/PlayAppView.swift +++ b/PlayCover/Views/App Views/PlayAppView.swift @@ -109,6 +109,7 @@ struct PlayAppView: View { Text("playapp.clearPreferences") }) Button(action: { + selected = nil Uninstaller.uninstallPopup(app) }, label: { Text("playapp.delete") From f64d20418fa06a62d19e33a98ace6ce28e55c383 Mon Sep 17 00:00:00 2001 From: Xyct <87l46110@gmail.com> Date: Sat, 4 Mar 2023 16:25:42 +0800 Subject: [PATCH 25/79] fix version control mark in jp localization strings --- PlayCover/ja.lproj/Localizable.strings | 4 ---- 1 file changed, 4 deletions(-) diff --git a/PlayCover/ja.lproj/Localizable.strings b/PlayCover/ja.lproj/Localizable.strings index 3ffcc9684..74dc5baaa 100644 --- a/PlayCover/ja.lproj/Localizable.strings +++ b/PlayCover/ja.lproj/Localizable.strings @@ -107,11 +107,7 @@ "playapp.install.createWrapper" = "アプリのコンテナーを作成中..."; /* (No Comment) */ -<<<<<<< HEAD "playapp.install.finished" = "完成"; -======= -"playapp.progress.finished" = "完了"; ->>>>>>> 5d52ecd (Translations update from Hosted Weblate (#803)) /* (No Comment) */ "playapp.install.installPlayTools" = "PlayToolsをインストール中..."; From 5055d1230998d571f9632d74e17e8af0eb6cc7cc Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Wed, 15 Mar 2023 21:05:07 -0600 Subject: [PATCH 26/79] PlayTools v2.1.0 --- Cartfile.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index 16eff4a61..94582fd84 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "PlayCover/PlayTools" "v2.0.7" +github "PlayCover/PlayTools" "v2.1.0" From 235274f828bf8639620c896bbb4f28fba52ba54e Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Wed, 15 Mar 2023 21:05:31 -0600 Subject: [PATCH 27/79] Bug fix release 2.0.5 --- PlayCover.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 0851a63f6..ba39fa294 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -815,7 +815,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 233; + CURRENT_PROJECT_VERSION = 291; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content"; @@ -830,7 +830,7 @@ ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 2.0.4; + MARKETING_VERSION = 2.0.5; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; @@ -918,7 +918,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 233; + CURRENT_PROJECT_VERSION = 291; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content"; @@ -933,7 +933,7 @@ ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 2.0.4; + MARKETING_VERSION = 2.0.5; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; From 2eae0ad5cf43ebc56f2f03f19681b2e178f4b5ff Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Wed, 15 Mar 2023 21:17:03 -0600 Subject: [PATCH 28/79] change inject cmdType for inject 1.1.0 --- PlayCover/Utils/PlayTools.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PlayCover/Utils/PlayTools.swift b/PlayCover/Utils/PlayTools.swift index 0d8f8ba59..19dac90c8 100644 --- a/PlayCover/Utils/PlayTools.swift +++ b/PlayCover/Utils/PlayTools.swift @@ -89,7 +89,7 @@ class PlayTools { static func installInIPA(_ exec: URL) throws { stripBinary(exec) Inject.injectMachO(machoPath: exec.path, - cmdType: LC_Type.LOAD_DYLIB, + cmdType: .loadDylib, backup: false, injectPath: playToolsPath.path, finishHandle: { result in @@ -129,7 +129,7 @@ class PlayTools { static func injectInIPA(_ exec: URL, payload: URL) throws { stripBinary(exec) Inject.injectMachO(machoPath: exec.path, - cmdType: LC_Type.LOAD_DYLIB, + cmdType: .loadDylib, backup: false, injectPath: "@executable_path/Frameworks/PlayTools.dylib", finishHandle: { result in @@ -183,7 +183,7 @@ class PlayTools { static func removeFromApp(_ exec: URL) { Inject.removeMachO(machoPath: exec.path, - cmdType: LC_Type.LOAD_DYLIB, + cmdType: .loadDylib, backup: false, injectPath: playToolsPath.path, finishHandle: { result in From eee940c17b71c25218317beb7aa20e01f02ab444 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Sat, 7 Oct 2023 19:20:45 -0600 Subject: [PATCH 29/79] fix: sidebar button --- PlayCover/Views/MainView.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PlayCover/Views/MainView.swift b/PlayCover/Views/MainView.swift index 471cfb65f..c14e03e95 100644 --- a/PlayCover/Views/MainView.swift +++ b/PlayCover/Views/MainView.swift @@ -44,6 +44,13 @@ struct MainView: View { Label("sidebar.ipaLibrary", systemImage: "arrow.down.circle") } } + .toolbar { + ToolbarItem { // Sits on the left by default + Button(action: toggleSidebar, label: { + Image(systemName: "sidebar.leading") + }) + } + } .onChange(of: sidebarGeom.size) { newSize in navWidth = newSize.width } @@ -88,13 +95,6 @@ struct MainView: View { .onAppear { self.selectedView = URLObserved.type == .source ? 2 : 1 } - .toolbar { - ToolbarItem { // Sits on the left by default - Button(action: toggleSidebar, label: { - Image(systemName: "sidebar.leading") - }) - } - } .overlay { HStack { if !collapsed { From b8b75b18b9780a170a0e588916ae33da34c97922 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Thu, 2 Nov 2023 05:17:32 -0600 Subject: [PATCH 30/79] Fix Discord RPC (#1130) * fix: discord rpc * fix error when container does not exist --- PlayCover.xcodeproj/project.pbxproj | 4 ++ PlayCover/AppInstaller/Installer.swift | 6 +-- PlayCover/Model/AppContainer.swift | 41 ++++++---------- PlayCover/Model/AppSettings.swift | 4 +- PlayCover/Model/Keymapping.swift | 4 +- PlayCover/Model/PlayApp.swift | 18 +++---- PlayCover/Utils/Cacher.swift | 12 ++--- .../Utils/Extensions/PlayAppExtensions.swift | 49 +++++++++++++++++++ .../Utils/Extensions/URLExtensions.swift | 28 +++++++++-- PlayCover/ViewModel/AppsVM.swift | 7 +-- PlayCover/Views/Uninstaller.swift | 30 +++++------- 11 files changed, 123 insertions(+), 80 deletions(-) create mode 100644 PlayCover/Utils/Extensions/PlayAppExtensions.swift diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 6b4a1e7e9..fd746ea0d 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -85,6 +85,7 @@ B6603E1128E206A300DEFA3F /* UninstallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1028E206A300DEFA3F /* UninstallSettings.swift */; }; B6603E1328E2257800DEFA3F /* Uninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1228E2257800DEFA3F /* Uninstaller.swift */; }; B6825C3528F3D23600E3015A /* InstallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6825C3428F3D23600E3015A /* InstallSettings.swift */; }; + B68FD80D2ACB642100683778 /* PlayAppExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68FD80C2ACB642100683778 /* PlayAppExtensions.swift */; }; B6AB53C929232B4F00039B2E /* KeyCodeNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AB53C829232B4F00039B2E /* KeyCodeNames.swift */; }; B6ABDA2A2971EEF700A46E80 /* ProgressVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABDA292971EEF700A46E80 /* ProgressVM.swift */; }; /* End PBXBuildFile section */ @@ -189,6 +190,7 @@ B6603E1028E206A300DEFA3F /* UninstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UninstallSettings.swift; sourceTree = ""; }; B6603E1228E2257800DEFA3F /* Uninstaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Uninstaller.swift; sourceTree = ""; }; B6825C3428F3D23600E3015A /* InstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallSettings.swift; sourceTree = ""; }; + B68FD80C2ACB642100683778 /* PlayAppExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayAppExtensions.swift; sourceTree = ""; }; B6AB53C829232B4F00039B2E /* KeyCodeNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCodeNames.swift; sourceTree = ""; }; B6ABDA292971EEF700A46E80 /* ProgressVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressVM.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -358,6 +360,7 @@ 8783D00A26B8C9E600171041 /* URLExtensions.swift */, 6ECB1D0D29798DFA00CD92AA /* DataExtensions.swift */, 6E25096E297F5032004D754C /* FileExtensions.swift */, + B68FD80C2ACB642100683778 /* PlayAppExtensions.swift */, ); path = Extensions; sourceTree = ""; @@ -695,6 +698,7 @@ 28361D662892800200B35EDB /* DeleteStoredGenshinUserData.swift in Sources */, 53D9DAF326C1849D0071959E /* PlayCoverError.swift in Sources */, 9286D296273A7E4200958DD3 /* AppSettings.swift in Sources */, + B68FD80D2ACB642100683778 /* PlayAppExtensions.swift in Sources */, 9272F19E273B74C800DFBEF1 /* AppsVM.swift in Sources */, 923421F7275F40300030CD7D /* AppContainer.swift in Sources */, ); diff --git a/PlayCover/AppInstaller/Installer.swift b/PlayCover/AppInstaller/Installer.swift index 92d1709c1..244fb3bd6 100644 --- a/PlayCover/AppInstaller/Installer.swift +++ b/PlayCover/AppInstaller/Installer.swift @@ -60,7 +60,7 @@ class Installer { let app = try ipa.unzip() InstallVM.shared.next(.library, 0.5, 0.55) try saveEntitlements(app) - let machos = try resolveValidMachOs(app) + let machos = resolveValidMachOs(app) app.validMachOs = machos InstallVM.shared.next(.playtools, 0.55, 0.85) @@ -150,14 +150,14 @@ class Installer { } /// Returns an array of URLs to MachO files within the app - static func resolveValidMachOs(_ baseApp: BaseApp) throws -> [URL] { + static func resolveValidMachOs(_ baseApp: BaseApp) -> [URL] { if let validMachOs = baseApp.validMachOs { return validMachOs } var resolved: [URL] = [] - try baseApp.url.enumerateContents { url, attributes in + baseApp.url.enumerateContents { url, attributes in guard attributes.isRegularFile == true, let fileSize = attributes.fileSize, fileSize > 4 else { return } diff --git a/PlayCover/Model/AppContainer.swift b/PlayCover/Model/AppContainer.swift index 910f60791..ca6955923 100644 --- a/PlayCover/Model/AppContainer.swift +++ b/PlayCover/Model/AppContainer.swift @@ -9,45 +9,32 @@ import Foundation struct AppContainer { - let bundleId: String - let containerUrl: URL private static let containersURL = FileManager.default.homeDirectoryForCurrentUser .appendingPathComponent("Library") .appendingPathComponent("Containers") - lazy var userPrefsUrl: URL = { - return containerUrl - .appendingPathComponent("Data") + let bundleId: String + var containerUrl: URL { + AppContainer.containersURL.appendingPathComponent(bundleId) + } + + var userPrefsUrl: URL { + containerUrl.appendingPathComponent("Data") .appendingPathComponent("Library") .appendingPathComponent("Preferences") .appendingPathComponent(bundleId) .appendingPathExtension("plist") - }() + } + + init(bundleId: String) { + self.bundleId = bundleId + } public func clear() { FileManager.default.delete(at: containerUrl) } - public static func containers() throws -> [String: AppContainer] { - var found = [String: AppContainer]() - - let directoryContents = try FileManager.default - .contentsOfDirectory(at: containersURL, includingPropertiesForKeys: nil, options: []) - - let subdirs = directoryContents.filter { $0.hasDirectoryPath } - for sub in subdirs { - let metadataPlist = sub.appendingPathComponent(".com.apple.containermanagerd.metadata") - .appendingPathExtension("plist") - - if FileManager.default.fileExists(atPath: metadataPlist.path) { - if let plist = NSDictionary(contentsOfFile: metadataPlist.path) { - if let bundleId = plist["MCMMetadataIdentifier"] as? String { - found[bundleId] = AppContainer(bundleId: bundleId, containerUrl: sub) - } - } - } - } - - return found + public func doesExist() -> Bool { + FileManager.default.fileExists(atPath: containerUrl.path) } } diff --git a/PlayCover/Model/AppSettings.swift b/PlayCover/Model/AppSettings.swift index 44d4b0fdc..4ecbeb9d5 100644 --- a/PlayCover/Model/AppSettings.swift +++ b/PlayCover/Model/AppSettings.swift @@ -92,16 +92,14 @@ class AppSettings { let settingsUrl: URL var openWithLLDB: Bool = false var openLLDBWithTerminal: Bool = true - var container: AppContainer? var settings: AppSettingsData { didSet { encode() } } - init(_ info: AppInfo, container: AppContainer?) { + init(_ info: AppInfo) { self.info = info - self.container = container settingsUrl = AppSettings.appSettingsDir.appendingPathComponent(info.bundleIdentifier) .appendingPathExtension("plist") settings = AppSettingsData() diff --git a/PlayCover/Model/Keymapping.swift b/PlayCover/Model/Keymapping.swift index 5d16f425b..a15debf94 100644 --- a/PlayCover/Model/Keymapping.swift +++ b/PlayCover/Model/Keymapping.swift @@ -109,7 +109,6 @@ class Keymapping { let info: AppInfo let keymapURL: URL - var container: AppContainer? var keymap: Keymap { get { do { @@ -134,9 +133,8 @@ class Keymapping { } } - init(_ info: AppInfo, container: AppContainer?) { + init(_ info: AppInfo) { self.info = info - self.container = container keymapURL = Keymapping.keymappingDir.appendingPathComponent("\(info.bundleIdentifier).plist") } diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index d3964af63..09eb613b1 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -8,7 +8,6 @@ import Foundation import IOKit.pwr_mgt class PlayApp: BaseApp { - private static let library = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("Library") var displaySleepAssertionID: IOPMAssertionID? public var isStarting = false @@ -17,6 +16,11 @@ class PlayApp: BaseApp { } var sessionDisableKeychain: Bool = false + override init(appUrl: URL) { + super.init(appUrl: appUrl) + self.loadDiscordIPC() + } + func launch() async { do { isStarting = true @@ -66,10 +70,6 @@ class PlayApp: BaseApp { func runAppExec() { let config = NSWorkspace.OpenConfiguration() - if settings.settings.injectIntrospection { - config.environment["DYLD_LIBRARY_PATH"] = "/usr/lib/system/introspection" - } - NSWorkspace.shared.openApplication( at: url, configuration: config, @@ -187,11 +187,11 @@ class PlayApp: BaseApp { lazy var playChainURL = PlayApp.playChainDirectory.appendingPathComponent(info.bundleIdentifier) - lazy var settings = AppSettings(info, container: container) + lazy var settings = AppSettings(info) - lazy var keymapping = Keymapping(info, container: container) + lazy var keymapping = Keymapping(info) - var container: AppContainer? + lazy var container = AppContainer(bundleId: info.bundleIdentifier) func hasPlayTools() -> Bool { do { @@ -242,7 +242,7 @@ class PlayApp: BaseApp { } func openAppCache() { - container?.containerUrl.showInFinderAndSelectLastComponent() + container.containerUrl.showInFinderAndSelectLastComponent() } func clearAllCache() { diff --git a/PlayCover/Utils/Cacher.swift b/PlayCover/Utils/Cacher.swift index f56e7130d..119b190e1 100755 --- a/PlayCover/Utils/Cacher.swift +++ b/PlayCover/Utils/Cacher.swift @@ -28,15 +28,11 @@ class Cacher { var bestResImage: NSImage? let compareStr = app.info.bundleIdentifier + app.info.bundleVersion - do { - try app.url.enumerateContents { file, _ in - if file.lastPathComponent.contains(app.info.primaryIconName), let icon = NSImage(contentsOf: file), - checkImageDimensions(icon, bestResImage) { - bestResImage = icon - } + app.url.enumerateContents(blocking: false) { file, _ in + if file.lastPathComponent.contains(app.info.primaryIconName), let icon = NSImage(contentsOf: file), + self.checkImageDimensions(icon, bestResImage) { + bestResImage = icon } - } catch { - Log.shared.error(error) } if let assetsExtractor = try? AssetsExtractor(appUrl: app.url) { diff --git a/PlayCover/Utils/Extensions/PlayAppExtensions.swift b/PlayCover/Utils/Extensions/PlayAppExtensions.swift new file mode 100644 index 000000000..00ed8306d --- /dev/null +++ b/PlayCover/Utils/Extensions/PlayAppExtensions.swift @@ -0,0 +1,49 @@ +// +// PlayAppExtensions.swift +// PlayCover +// +// Created by TheMoonThatRises on 10/2/23. +// + +import Foundation + +extension PlayApp { + func loadDiscordIPC() { + if self.container.doesExist() { + let appTmp = self.container.containerUrl.appendingPathComponent("Data") + .appendingPathComponent("tmp") + + try? FileManager.default.createDirectory(at: appTmp, withIntermediateDirectories: false) + + appTmp.enumerateContents(options: []) { url, type in + if url.lastPathComponent.contains("discord-ipc-") && (type.isSymbolicLink ?? true) { + FileManager.default.delete(at: url) + } + } + + guard self.settings.settings.discordActivity.enable else { + return + } + + let userTmp = FileManager.default.temporaryDirectory.path + + for ipcPort in 0..<10 { + let socketPath = userTmp + "/discord-ipc-\(ipcPort)" + if FileManager.default.fileExists(atPath: socketPath) { + do { + try FileManager.default.createSymbolicLink(atPath: appTmp + .appendingPathComponent("discord-ipc-\(ipcPort)").path, + withDestinationPath: socketPath) + print("Successfully linked discordipc for \(self.info.bundleIdentifier)") + return + } catch { + print(error) + continue + } + } + } + + print("Unable to link discordipc for \(self.info.bundleIdentifier)") + } + } +} diff --git a/PlayCover/Utils/Extensions/URLExtensions.swift b/PlayCover/Utils/Extensions/URLExtensions.swift index 07032ea7f..ede8b3c5a 100644 --- a/PlayCover/Utils/Extensions/URLExtensions.swift +++ b/PlayCover/Utils/Extensions/URLExtensions.swift @@ -74,19 +74,37 @@ extension URL { } // Wraps NSFileEnumerator since the geniuses at corelibs-foundation decided it should be completely untyped - func enumerateContents(_ callback: (URL, URLResourceValues) throws -> Void) throws { + func enumerateContents(blocking: Bool = true, + includingPropertiesForKeys keys: [URLResourceKey]? = nil, + options: FileManager.DirectoryEnumerationOptions? = nil, + _ callback: @escaping(URL, URLResourceValues) throws -> Void) { guard let enumerator = FileManager.default.enumerator( at: self, - includingPropertiesForKeys: [.isRegularFileKey], - options: [.skipsHiddenFiles, .skipsPackageDescendants]) else { + includingPropertiesForKeys: keys ?? [.isRegularFileKey], + options: options ?? [.skipsHiddenFiles, .skipsPackageDescendants]) else { return } + let queue = OperationQueue() + queue.name = "io.playcover.PlayCover.URLExtension" + queue.qualityOfService = .userInitiated + queue.maxConcurrentOperationCount = 15 + for case let fileURL as URL in enumerator { - do { - try callback(fileURL, fileURL.resourceValues(forKeys: [.isRegularFileKey, .fileSizeKey])) + queue.addOperation { + do { + try callback(fileURL, fileURL.resourceValues(forKeys: [.isRegularFileKey, .fileSizeKey])) + } catch { + // Don't show error, as there could be many files within the folder + // that would fail the callback + print(error) + } } } + + if blocking { + queue.waitUntilAllOperationsAreFinished() + } } func appendingEscapedPathComponent(_ pathComponent: String) -> URL { diff --git a/PlayCover/ViewModel/AppsVM.swift b/PlayCover/ViewModel/AppsVM.swift index b1043b328..ec642934b 100644 --- a/PlayCover/ViewModel/AppsVM.swift +++ b/PlayCover/ViewModel/AppsVM.swift @@ -27,7 +27,6 @@ class AppsVM: ObservableObject { apps.removeAll() do { - let containers = try AppContainer.containers() let directoryContents = try FileManager.default .contentsOfDirectory(at: PlayTools.playCoverContainer, includingPropertiesForKeys: nil, options: []) @@ -39,10 +38,8 @@ class AppsVM: ObservableObject { .appendingPathExtension("plist") .path) { let app = PlayApp(appUrl: sub) - if let container = containers[app.info.bundleIdentifier] { - app.container = container - print("Application installed under:", sub.path) - } + print("Application installed under:", sub.path) + apps.append(app) if searchText.isEmpty || app.searchText.contains(searchText.lowercased()) { filteredApps.append(app) diff --git a/PlayCover/Views/Uninstaller.swift b/PlayCover/Views/Uninstaller.swift index a5882f742..7df272d7e 100644 --- a/PlayCover/Views/Uninstaller.swift +++ b/PlayCover/Views/Uninstaller.swift @@ -153,27 +153,23 @@ class Uninstaller { let bundleIds = AppsVM.shared.apps.map { $0.info.bundleIdentifier } let appNames = AppsVM.shared.apps.map { $0.info.displayName } - do { - for url in pruneURLs { - try url.enumerateContents { file, _ in - let bundleId = file.deletingPathExtension().lastPathComponent - if !bundleIds.contains(bundleId) { - clearExternalCache(bundleId) - - FileManager.default.delete(at: file) - } + for url in pruneURLs { + url.enumerateContents(options: []) { file, _ in + let bundleId = file.deletingPathExtension().lastPathComponent + if !bundleIds.contains(bundleId) { + clearExternalCache(bundleId) + + FileManager.default.delete(at: file) } } - for url in otherPruneURLs { - try url.enumerateContents { file, _ in - let appName = file.deletingPathExtension().lastPathComponent - if !appNames.contains(appName) { - FileManager.default.delete(at: file) - } + } + for url in otherPruneURLs { + url.enumerateContents(options: []) { file, _ in + let appName = file.deletingPathExtension().lastPathComponent + if !appNames.contains(appName) { + FileManager.default.delete(at: file) } } - } catch { - Log.shared.error(error) } } } From 4c504e35ccf686a8409e545c936c4488a8a66a26 Mon Sep 17 00:00:00 2001 From: ytai <653297351@qq.com> Date: Tue, 5 Dec 2023 05:36:13 +0800 Subject: [PATCH 31/79] Add toggle for scroll wheel (#1215) * Add * Add i18n string --- PlayCover/Model/AppSettings.swift | 2 ++ PlayCover/Views/AppSettingsView.swift | 5 +++++ PlayCover/en.lproj/Localizable.strings | 2 ++ 3 files changed, 9 insertions(+) diff --git a/PlayCover/Model/AppSettings.swift b/PlayCover/Model/AppSettings.swift index 4ecbeb9d5..97213ba2b 100644 --- a/PlayCover/Model/AppSettings.swift +++ b/PlayCover/Model/AppSettings.swift @@ -40,6 +40,7 @@ struct AppSettingsData: Codable { var injectIntrospection = false var rootWorkDir = true var noKMOnInput = true + var enableScrollWheel = true init() {} @@ -69,6 +70,7 @@ struct AppSettingsData: Codable { injectIntrospection = try container.decodeIfPresent(Bool.self, forKey: .injectIntrospection) ?? false rootWorkDir = try container.decodeIfPresent(Bool.self, forKey: .rootWorkDir) ?? true noKMOnInput = try container.decodeIfPresent(Bool.self, forKey: .noKMOnInput) ?? true + enableScrollWheel = try container.decodeIfPresent(Bool.self, forKey: .enableScrollWheel) ?? true } } diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index b0336319f..fce57f3c1 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -156,6 +156,11 @@ struct KeymappingView: View { Toggle("settings.toggle.autoKM", isOn: $settings.settings.noKMOnInput) .help("settings.toggle.autoKM.help") } + HStack { + Toggle("settings.toggle.enableScrollWheel", isOn: $settings.settings.keymapping) + .help("settings.toggle.enableScrollWheel.help") + Spacer() + } HStack { Text(String( format: NSLocalizedString("settings.slider.mouseSensitivity", comment: ""), diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index 1edb0dfba..6814893e1 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -161,6 +161,8 @@ "settings.slider.mouseSensitivity" = "Mouse sensitivity: %.f"; "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel" +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping" "settings.tab.graphics" = "Graphics"; "settings.picker.iosDevice" = "iOS device:"; From a974b5329a65814c4c9394c3d77767b4cb01488f Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:23:06 -0700 Subject: [PATCH 32/79] fix: missing semi-colon in en localisation --- PlayCover/en.lproj/Localizable.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index 6814893e1..eb53b65b7 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -161,8 +161,8 @@ "settings.slider.mouseSensitivity" = "Mouse sensitivity: %.f"; "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; -"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel" -"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping" +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; "settings.tab.graphics" = "Graphics"; "settings.picker.iosDevice" = "iOS device:"; From 9269b7666f2ada016c7087682ddffddfb4134174 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:21:12 -0700 Subject: [PATCH 33/79] Use Application ID when storing apps (#1100) * feat: init of using app id * fix: discord rpc * add and move alias function * update bundleid cache * fix cache prune * fix merge * fix removing wrong file --- PlayCover/AppInstaller/Installer.swift | 4 +- PlayCover/Model/PlayApp.swift | 47 +++++-------- .../Utils/Extensions/PlayAppExtensions.swift | 19 +++++ PlayCover/ViewModel/AppsVM.swift | 70 ++++++++++++++++++- PlayCover/Views/AppSettingsView.swift | 15 ++-- PlayCover/Views/Uninstaller.swift | 70 +++++++++++++------ PlayCover/en.lproj/Localizable.strings | 3 +- 7 files changed, 160 insertions(+), 68 deletions(-) diff --git a/PlayCover/AppInstaller/Installer.swift b/PlayCover/AppInstaller/Installer.swift index 244fb3bd6..5278109cb 100644 --- a/PlayCover/AppInstaller/Installer.swift +++ b/PlayCover/AppInstaller/Installer.swift @@ -207,8 +207,8 @@ class Installer { let info = AppInfo(contentsOf: baseApp.url .appendingPathComponent("Info") .appendingPathExtension("plist")) - let location = PlayTools.playCoverContainer - .appendingEscapedPathComponent(info.displayName) + let location = AppsVM.appDirectory + .appendingEscapedPathComponent(info.bundleIdentifier) .appendingPathExtension("app") if FileManager.default.fileExists(atPath: location.path) { try FileManager.default.removeItem(at: location) diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index 09eb613b1..6b9f8a2df 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -8,18 +8,29 @@ import Foundation import IOKit.pwr_mgt class PlayApp: BaseApp { + public static let bundleIDCacheURL = PlayTools.playCoverContainer.appendingPathComponent("CACHE") var displaySleepAssertionID: IOPMAssertionID? public var isStarting = false - var searchText: String { - info.displayName.lowercased().appending(" ").appending(info.bundleName).lowercased() + public static var bundleIDCache: [String] { + get throws { + (try String(contentsOf: bundleIDCacheURL)).split(whereSeparator: \.isNewline).map({ String($0) }) + } } - var sessionDisableKeychain: Bool = false override init(appUrl: URL) { super.init(appUrl: appUrl) - self.loadDiscordIPC() + + removeAlias() + createAlias() + + loadDiscordIPC() + } + + var searchText: String { + info.displayName.lowercased().appending(" ").appending(info.bundleName).lowercased() } + var sessionDisableKeychain: Bool = false func launch() async { do { @@ -71,7 +82,7 @@ class PlayApp: BaseApp { let config = NSWorkspace.OpenConfiguration() NSWorkspace.shared.openApplication( - at: url, + at: aliasURL, configuration: config, completionHandler: { runningApp, error in guard error == nil else { return } @@ -183,7 +194,7 @@ class PlayApp: BaseApp { static let playChainDirectory = PlayTools.playCoverContainer.appendingPathComponent("PlayChain") - lazy var aliasURL = PlayApp.aliasDirectory.appendingPathComponent(name) + lazy var aliasURL = PlayApp.aliasDirectory.appendingPathComponent(name).appendingPathExtension("app") lazy var playChainURL = PlayApp.playChainDirectory.appendingPathComponent(info.bundleIdentifier) @@ -254,23 +265,6 @@ class PlayApp: BaseApp { FileManager.default.delete(at: playChainURL.appendingPathExtension("keyCover")) } - func createAlias() { - do { - try FileManager.default.createDirectory(atPath: PlayApp.aliasDirectory.path, - withIntermediateDirectories: true, - attributes: nil) - let data = try url.bookmarkData(options: .suitableForBookmarkFile, - includingResourceValuesForKeys: nil, relativeTo: nil) - try URL.writeBookmarkData(data, to: aliasURL) - } catch { - Log.shared.log(error.localizedDescription) - } - } - - func removeAlias() { - FileManager.default.delete(at: aliasURL) - } - func deleteApp() { FileManager.default.delete(at: URL(fileURLWithPath: url.path)) AppsVM.shared.fetchApps() @@ -278,17 +272,14 @@ class PlayApp: BaseApp { func sign() { do { - let tmpDir = try FileManager.default.url(for: .itemReplacementDirectory, - in: .userDomainMask, - appropriateFor: URL(fileURLWithPath: "/Users"), - create: true) + let tmpDir = FileManager.default.temporaryDirectory let tmpEnts = tmpDir .appendingEscapedPathComponent(ProcessInfo().globallyUniqueString) .appendingPathExtension("plist") let conf = try Entitlements.composeEntitlements(self) try conf.store(tmpEnts) try Shell.signAppWith(executable, entitlements: tmpEnts) - try FileManager.default.removeItem(at: tmpDir) + try FileManager.default.removeItem(at: tmpEnts) } catch { print(error) Log.shared.error(error) diff --git a/PlayCover/Utils/Extensions/PlayAppExtensions.swift b/PlayCover/Utils/Extensions/PlayAppExtensions.swift index 00ed8306d..ef762bb14 100644 --- a/PlayCover/Utils/Extensions/PlayAppExtensions.swift +++ b/PlayCover/Utils/Extensions/PlayAppExtensions.swift @@ -46,4 +46,23 @@ extension PlayApp { print("Unable to link discordipc for \(self.info.bundleIdentifier)") } } + + func createAlias() { + do { + try FileManager.default.createDirectory(atPath: aliasURL.path, + withIntermediateDirectories: true, + attributes: nil) + url.enumerateContents(options: [.skipsSubdirectoryDescendants]) { ctxUrl, _ in + try FileManager.default.createSymbolicLink( + at: self.aliasURL.appendingPathComponent(ctxUrl.lastPathComponent), + withDestinationURL: ctxUrl) + } + } catch { + Log.shared.log(error.localizedDescription) + } + } + + func removeAlias() { + FileManager.default.delete(at: aliasURL) + } } diff --git a/PlayCover/ViewModel/AppsVM.swift b/PlayCover/ViewModel/AppsVM.swift index ec642934b..4943e51f3 100644 --- a/PlayCover/ViewModel/AppsVM.swift +++ b/PlayCover/ViewModel/AppsVM.swift @@ -7,9 +7,16 @@ import Foundation class AppsVM: ObservableObject { + public static let versionsFile = PlayTools.playCoverContainer.appendingPathComponent("VERSION") + public static var currentVersion: String { + (try? String(contentsOf: AppsVM.versionsFile)) ?? "2" + } + public static let appDirectory = PlayTools.playCoverContainer.appendingPathComponent("Applications") + static let shared = AppsVM() private init() { + checkForUpdate() PlayTools.installOnSystem() fetchApps() } @@ -19,6 +26,44 @@ class AppsVM: ObservableObject { @Published var searchText: String = "" @Published var updatingApps = true + func checkForUpdate() { + do { + switch AppsVM.currentVersion { + case "2": + try updateFromV2ToV3() + default: + return + } + } catch { + Log.shared.error(error) + } + } + + private func updateFromV2ToV3() throws { + try FileManager.default.createDirectory(at: AppsVM.appDirectory, withIntermediateDirectories: true) + + let directoryContents = try FileManager.default + .contentsOfDirectory(at: PlayTools.playCoverContainer, includingPropertiesForKeys: nil, options: []) + + let subdirs = directoryContents.filter { $0.hasDirectoryPath } + + for sub in subdirs { + if sub.pathExtension.contains("app") && + FileManager.default.fileExists(atPath: sub.appendingPathComponent("Info") + .appendingPathExtension("plist") + .path) { + let app = PlayApp(appUrl: sub) + app.removeAlias() + try FileManager.default.moveItem(at: app.url, + to: AppsVM.appDirectory + .appendingPathComponent(app.info.bundleIdentifier) + .appendingPathExtension("app")) + } + } + + try "3".write(to: AppsVM.versionsFile, atomically: false, encoding: .utf8) + } + func fetchApps() { Task { @MainActor in updatingApps = true @@ -28,7 +73,7 @@ class AppsVM: ObservableObject { do { let directoryContents = try FileManager.default - .contentsOfDirectory(at: PlayTools.playCoverContainer, includingPropertiesForKeys: nil, options: []) + .contentsOfDirectory(at: AppsVM.appDirectory, includingPropertiesForKeys: nil, options: []) let subdirs = directoryContents.filter { $0.hasDirectoryPath } @@ -46,13 +91,32 @@ class AppsVM: ObservableObject { } } } - - } catch let error as NSError { + } catch { print(error) } filteredApps.sort(by: { $0.name.lowercased() < $1.name.lowercased() }) + do { + if !FileManager.default.fileExists(atPath: PlayApp.bundleIDCacheURL.path), + let firstBundleID = apps.first?.info.bundleIdentifier { + try "\(firstBundleID)\n" + .write(to: PlayApp.bundleIDCacheURL, atomically: false, encoding: .utf8) + } + + for bundleId in apps.map({ $0.info.bundleIdentifier }) + where !(try PlayApp.bundleIDCache).contains(bundleId) { + if let bundleID = "\(bundleId)\n".data(using: .utf8) { + let cacheFile = try FileHandle(forUpdating: PlayApp.bundleIDCacheURL) + try cacheFile.seekToEnd() + try cacheFile.write(contentsOf: bundleID) + try cacheFile.close() + } + } + } catch { + Log.shared.error(error) + } + updatingApps = false } } diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index fce57f3c1..0245752be 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -608,16 +608,6 @@ struct MiscView: View { } } Spacer() - Button((hasAlias ?? true) ? "settings.removeFromLaunchpad" : "settings.addToLaunchpad") { - closeView.toggle() - if !(hasAlias ?? true) { - app.createAlias() - hasAlias = true - } else { - app.removeAlias() - hasAlias = false - } - } } Spacer() .frame(height: 20) @@ -694,6 +684,11 @@ struct InfoView: View { Spacer() Text("\(info.url.relativePath)") } + HStack { + Text("settings.info.alias") + Spacer() + Text("\(PlayApp.aliasDirectory.appendingPathComponent(info.bundleIdentifier))") + } } .listStyle(.bordered(alternatesRowBackgrounds: true)) .padding() diff --git a/PlayCover/Views/Uninstaller.swift b/PlayCover/Views/Uninstaller.swift index 7df272d7e..474b49de4 100644 --- a/PlayCover/Views/Uninstaller.swift +++ b/PlayCover/Views/Uninstaller.swift @@ -21,9 +21,6 @@ class Uninstaller { PlayTools.playCoverContainer.appendingPathComponent("Keymapping"), PlayTools.playCoverContainer.appendingPathComponent("PlayChain") ] - private static let otherPruneURLs: [URL] = [ - PlayApp.aliasDirectory - ] private static let cacheURLs: [URL] = [ Uninstaller.libraryUrl.appendingPathComponent("Containers"), Uninstaller.libraryUrl.appendingPathComponent("Application Scripts"), @@ -112,20 +109,26 @@ class Uninstaller { } static func uninstall(_ app: PlayApp) { + var uninstallNum = 0 + if UninstallPreferences.shared.clearAppData { app.clearAllCache() + uninstallNum += 1 } if UninstallPreferences.shared.removeAppKeymap { FileManager.default.delete(at: app.keymapping.keymapURL) + uninstallNum += 1 } if UninstallPreferences.shared.removeAppSettings { FileManager.default.delete(at: app.settings.settingsUrl) + uninstallNum += 1 } if UninstallPreferences.shared.removeAppEntitlements { FileManager.default.delete(at: app.entitlements) + uninstallNum += 1 } if UninstallPreferences.shared.removePlayChain { @@ -137,39 +140,60 @@ class Uninstaller { // KeyCover encrypted chain let keyCoverURL = url.appendingPathExtension("keyCover") FileManager.default.delete(at: keyCoverURL) + uninstallNum += 1 } app.removeAlias() app.deleteApp() - } - static func clearExternalCache(_ bundleId: String) { - for cache in cacheURLs { - FileManager.default.delete(at: cache.appendingPathComponent(bundleId)) + if uninstallNum >= 5 { + do { + let apps = (try PlayApp.bundleIDCache).filter({ $0 != app.info.bundleIdentifier }) + .joined(separator: "\n") + "\n" + + try apps.write(to: PlayApp.bundleIDCacheURL, atomically: false, encoding: .utf8) + } catch { + Log.shared.error(error) + } } } - static func pruneFiles() { - let bundleIds = AppsVM.shared.apps.map { $0.info.bundleIdentifier } - let appNames = AppsVM.shared.apps.map { $0.info.displayName } - - for url in pruneURLs { - url.enumerateContents(options: []) { file, _ in - let bundleId = file.deletingPathExtension().lastPathComponent - if !bundleIds.contains(bundleId) { - clearExternalCache(bundleId) - - FileManager.default.delete(at: file) + static func clearExternalCache(_ bundleId: String) { + do { + for cache in cacheURLs { + cache.enumerateContents(options: []) { file, _ in + if file.path.contains(bundleId) { + try FileManager.default.trashItem(at: file, resultingItemURL: nil) + } } } } - for url in otherPruneURLs { - url.enumerateContents(options: []) { file, _ in - let appName = file.deletingPathExtension().lastPathComponent - if !appNames.contains(appName) { - FileManager.default.delete(at: file) + } + + static func pruneFiles() { + do { + let bundleIds = AppsVM.shared.apps.map { $0.info.bundleIdentifier } + let danglingItems = try PlayApp.bundleIDCache.filter { !bundleIds.contains($0) } + + var fullPruneURLs = pruneURLs + fullPruneURLs.append(contentsOf: cacheURLs) + + var prunedIds: [String] = [] + + for url in fullPruneURLs { + url.enumerateContents(options: []) { file, _ in + let bundleId = file.deletingPathExtension().lastPathComponent + if danglingItems.contains(bundleId) { + try FileManager.default.trashItem(at: file, resultingItemURL: nil) + prunedIds.append(bundleId) + } } } + + try "\(PlayApp.bundleIDCache.filter({ !Set(prunedIds).contains($0) }).joined(separator: "\n"))\n" + .write(to: PlayApp.bundleIDCacheURL, atomically: false, encoding: .utf8) + } catch { + Log.shared.error(error) } } } diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index eb53b65b7..17514b4e1 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -196,8 +196,6 @@ "settings.applicationCategoryType" = "Application Type"; "settings.removePlayTools" = "Remove PlayTools"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; "settings.info.displayName" = "Display name:"; "settings.info.bundleName" = "Bundle name:"; @@ -207,6 +205,7 @@ "settings.info.minimumOSVersion" = "Minimum OS version:"; "settings.info.playTools" = "PlayTools installed:"; "settings.info.url" = "URL:"; +"settings.info.alias" = "Alias:"; "settings.resetSettings" = "Reset settings"; "settings.resetKm" = "Reset keymapping"; From f853d5b36f0b74f82bbc832c6ae0718021d256fd Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 8 Dec 2023 18:58:59 -0700 Subject: [PATCH 34/79] move create-dmg to brew --- .github/workflows/1.build_release.yml | 3 +-- .github/workflows/2.nightly_release.yml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 23769aeec..d13c1c7c8 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -19,9 +19,8 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick + brew install graphicsmagick imagemagick create-dmg bundle install - npm install --global create-dmg - name: Fastlane Release shell: bash diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index da7d8fba3..b30846d67 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -15,9 +15,8 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick + brew install graphicsmagick imagemagick create-dmg bundle install - npm install --global create-dmg - name: Set build number shell: bash From f650cf0c9c209a2e6727b7a88b242a397754d255 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 8 Dec 2023 19:16:24 -0700 Subject: [PATCH 35/79] update fastlane --- .github/workflows/1.build_release.yml | 1 + .github/workflows/2.nightly_release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index d13c1c7c8..c445908d0 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -20,6 +20,7 @@ jobs: shell: bash run: | brew install graphicsmagick imagemagick create-dmg + gem install fastlane bundle install - name: Fastlane Release diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index b30846d67..3ea6c5fe5 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -16,6 +16,7 @@ jobs: shell: bash run: | brew install graphicsmagick imagemagick create-dmg + gem install fastlane bundle install - name: Set build number From 52e838dd5c131d6569a4d12c1a7dfd3f5b5c3bb5 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Sat, 9 Dec 2023 11:10:45 -0700 Subject: [PATCH 36/79] actually fix nightly build (#1253) --- .github/workflows/1.build_release.yml | 4 +++- .github/workflows/2.nightly_release.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index c445908d0..c0dfb28af 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -19,9 +19,11 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick create-dmg + brew install graphicsmagick imagemagick gem install fastlane bundle install + pip install setuptools + npm install --global create-dmg - name: Fastlane Release shell: bash diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 3ea6c5fe5..1115daa64 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -15,9 +15,11 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick create-dmg + brew install graphicsmagick imagemagick gem install fastlane bundle install + pip install setuptools + npm install --global create-dmg - name: Set build number shell: bash From aa4edac67fc251a38676b08b5537f95ad30e3040 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 9 Dec 2023 21:12:03 +0100 Subject: [PATCH 37/79] Translations update from Hosted Weblate (#1000) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Turkish) Currently translated at 96.9% (258 of 266 strings) Translated using Weblate (Turkish) Currently translated at 97.3% (258 of 265 strings) Translated using Weblate (Turkish) Currently translated at 97.3% (258 of 265 strings) Translated using Weblate (Turkish) Currently translated at 98.0% (258 of 263 strings) Co-authored-by: Anonymous Co-authored-by: Claws\" Kayvan Co-authored-by: Hosted Weblate Co-authored-by: serkan ege Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 88.3% (235 of 266 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 88.6% (235 of 265 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 88.3% (234 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Luiz Oliveira Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (German) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (German) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (German) Currently translated at 99.2% (263 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Danish) Currently translated at 87.9% (234 of 266 strings) Translated using Weblate (Danish) Currently translated at 88.3% (234 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/da/ Translation: PlayCover/PlayCover * Translated using Weblate (Russian) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Russian) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Russian) Currently translated at 75.4% (200 of 265 strings) Translated using Weblate (Russian) Currently translated at 73.9% (196 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Stanislav Co-authored-by: Vladimir Lapskiy Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 60.1% (160 of 266 strings) Translated using Weblate (Romanian) Currently translated at 60.3% (160 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 88.7% (236 of 266 strings) Translated using Weblate (Japanese) Currently translated at 89.0% (236 of 265 strings) Translated using Weblate (Japanese) Currently translated at 87.9% (233 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Tatsuya Kozato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Translated using Weblate (Vietnamese) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Vietnamese) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Vietnamese) Currently translated at 88.3% (234 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Thanh Nguyen Co-authored-by: Trần Thanh Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 74.4% (198 of 266 strings) Translated using Weblate (Hindi) Currently translated at 74.7% (198 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Translated using Weblate (Indonesian) Currently translated at 71.8% (191 of 266 strings) Translated using Weblate (Indonesian) Currently translated at 60.1% (160 of 266 strings) Translated using Weblate (Indonesian) Currently translated at 60.3% (160 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Reza Almanda Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Spanish) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Spanish) Currently translated at 88.3% (234 of 265 strings) Co-authored-by: Adolfo Jayme Barrientos Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 83.4% (222 of 266 strings) Translated using Weblate (French) Currently translated at 83.7% (222 of 265 strings) Translated using Weblate (French) Currently translated at 83.3% (221 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: jluo3364 Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 75.5% (201 of 266 strings) Translated using Weblate (Persian) Currently translated at 75.8% (201 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Korean) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Korean) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Korean) Currently translated at 87.1% (231 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Minseo Lee Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 87.1% (231 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Chamomile Translation Co-authored-by: Hosted Weblate Co-authored-by: Mojito765 Co-authored-by: VP <51seer.vincent@gmail.com> Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (266 of 266 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 99.6% (265 of 266 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (265 of 265 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 99.2% (263 of 265 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Simon Co-authored-by: weng weng Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover --------- Co-authored-by: Claws\" Kayvan Co-authored-by: serkan ege Co-authored-by: Luiz Oliveira Co-authored-by: SkyrilHD Co-authored-by: Stanislav Co-authored-by: Vladimir Lapskiy Co-authored-by: Tatsuya Kozato Co-authored-by: Thanh Nguyen Co-authored-by: Trần Thanh Co-authored-by: Reza Almanda Co-authored-by: Adolfo Jayme Barrientos Co-authored-by: gallegonovato Co-authored-by: jluo3364 Co-authored-by: Minseo Lee Co-authored-by: Chamomile Translation Co-authored-by: Mojito765 Co-authored-by: VP <51seer.vincent@gmail.com> Co-authored-by: Simon Co-authored-by: weng weng --- PlayCover/da.lproj/Localizable.strings | 3 + PlayCover/de.lproj/Localizable.strings | 3 + PlayCover/es.lproj/Localizable.strings | 83 ++++--- PlayCover/fa.lproj/Localizable.strings | 3 + PlayCover/fr.lproj/Localizable.strings | 5 +- PlayCover/hi.lproj/Localizable.strings | 3 + PlayCover/id.lproj/Localizable.strings | 61 ++--- PlayCover/ja.lproj/Localizable.strings | 9 +- PlayCover/ko.lproj/Localizable.strings | 255 ++++++++++---------- PlayCover/pt-br.lproj/Localizable.strings | 5 +- PlayCover/ro.lproj/Localizable.strings | 3 + PlayCover/ru.lproj/Localizable.strings | 225 ++++++++--------- PlayCover/tr.lproj/Localizable.strings | 131 +++++----- PlayCover/vi.lproj/Localizable.strings | 79 +++--- PlayCover/zh-Hans.lproj/Localizable.strings | 5 +- PlayCover/zh-Hant.lproj/Localizable.strings | 115 ++++----- 16 files changed, 518 insertions(+), 470 deletions(-) diff --git a/PlayCover/da.lproj/Localizable.strings b/PlayCover/da.lproj/Localizable.strings index 840457a54..a38972441 100644 --- a/PlayCover/da.lproj/Localizable.strings +++ b/PlayCover/da.lproj/Localizable.strings @@ -261,3 +261,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/de.lproj/Localizable.strings b/PlayCover/de.lproj/Localizable.strings index 39af94613..401b79843 100644 --- a/PlayCover/de.lproj/Localizable.strings +++ b/PlayCover/de.lproj/Localizable.strings @@ -418,3 +418,6 @@ "keycover.unlockPrompt.title" = "Gib dein Master-Passwort ein, um KeyCover zu entsperren"; "keycover.alert.title" = "Schlüsselbund wurde nicht entsperrt"; "keycover.alert.content" = "Der Zugriff auf den Schlüsselbund wurde für die aktuelle Sitzung deaktiviert"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Tastenbelegung automatisch deaktivieren, wenn eine Texteingabe erkannt wird"; +"settings.applicationCategoryType" = "Anwendungsart"; diff --git a/PlayCover/es.lproj/Localizable.strings b/PlayCover/es.lproj/Localizable.strings index be1db9763..3013f5fef 100644 --- a/PlayCover/es.lproj/Localizable.strings +++ b/PlayCover/es.lproj/Localizable.strings @@ -32,19 +32,19 @@ "button.Cancel" = "Cancelar"; /* (No Comment) */ -"button.Close" = "Salir"; +"button.Close" = "Cerrar"; /* (No Comment) */ "button.Install" = "Instalar"; /* (No Comment) */ -"button.OK" = "OK"; +"button.OK" = "Aceptar"; /* (No Comment) */ "button.Proceed" = "Continuar"; /* (No Comment) */ -"error.corruptedIPA" = "Este archivo .ipa está dañado. No contiene un archivo \"Info.plist\"."; +"error.corruptedIPA" = "Este archivo .ipa está dañado. No contiene un archivo «Info.plist»."; /* (No Comment) */ "error.waitInstallation" = "¡Por favor espere a que finalice la instalación!"; @@ -77,7 +77,7 @@ "notification.appInstalled.message" = "¡Compruébelo en PlayCover!"; /* (No Comment) */ -"playapp.activateAccount" = "Restaurar cuenta"; +"playapp.activateAccount" = "Cambiar cuenta"; /* (No Comment) */ "playapp.clearCache" = "Eliminar datos de la aplicación"; @@ -200,7 +200,7 @@ "soundAlert.messageText" = "¡Se ha detectado una configuración de audio incorrecta!"; /* (No Comment) */ -"soundAlert.successText" = "Frecuencia de muestreo del dispositivo de salida actual está establecida en 48 kHz"; +"soundAlert.successText" = "La tasa de muestreo del dispositivo de salida actual está establecida en 48 kHz"; /* (No Comment) */ "storeAccount.deleteAcc" = "Eliminar una cuenta"; @@ -245,8 +245,8 @@ "storeAccount.alert.restoreAccount.msg" = "Esto anulará la sesión de su cuenta actual."; "storeAccount.alert.deleteAccount" = "¿Confirma que quiere eliminar la cuenta?"; "storeAccount.alert.deleteAccount.button" = "Eliminar cuenta"; -"alert.moveAppToApplications.title" = "Mover a la carpeta de Aplicaciones?"; -"alert.moveAppToApplications.subtitle" = "PlayCover debe estar en la carpeta de Aplicaciones para funcionar correctamente. Presione el botón de abajo para mover PlayCover automáticamente."; +"alert.moveAppToApplications.title" = "¿Quiere moverlo a la carpeta Aplicaciones?"; +"alert.moveAppToApplications.subtitle" = "PlayCover debe estar en la carpeta Aplicaciones para funcionar correctamente. Pulse el botón de abajo para que PlayCover se mueva automáticamente."; "button.Quit" = "Salir"; "error.appEncrypted" = "¡Esta aplicación está encriptada! Por favor utilice un IPA descifrado. ¡Los IPA de iMazing no son compatibles!"; "error.appCorrupted" = "Algo ha ido mal con este IPA. Por favor, intente utilizar otro archivo IPA."; @@ -351,8 +351,8 @@ "alert.power.subtitle" = "Algunas aplicaciones no funcionarán con el modo de bajo consumo activado. Se recomienda desactivarlo."; "ipaLibrary.version.same" = "Aplicación ya instalada"; "ipaLibrary.download" = "Descargar"; -"ipaLibrary.version.older" = "Esta versión es más vieja que la instalada actualmente"; -"ipaLibrary.version.newer" = "Esta versión es más nueva que la instalada actualmente"; +"ipaLibrary.version.older" = "Esta versión es más antigua que la instalada actualmente"; +"ipaLibrary.version.newer" = "Esta versión es más reciente que la instalada actualmente"; "ipaLibrary.alert.download" = "¿Confirma que quiere descargar esta versión de %@?"; "alert.differentBundleIdKeymap.message" = "Esta asignación de teclas pudo haber sido creada para otra aplicación."; "alert.differentBundleIdKeymap.text" = "¿Confirma que quiere importar esta asignación de teclas?"; @@ -370,8 +370,8 @@ "settings.addToLaunchpad" = "Agregar al Launchpad"; "settings.removeFromLaunchpad" = "Quitar del Launchpad"; "playapp.download.integrityCheck" = "Verificar la integridad de los archivos:"; -"playapp.download.differentChecksum" = "¡Diferentes sumas de control! ¿Desea continuar con la instalación?"; -"playapp.download.differentChecksumDesc" = "Esperado \"%@\", obtenido \"%@\""; +"playapp.download.differentChecksum" = "Las sumas de control difieren. ¿Quiere proceder con la instalación?"; +"playapp.download.differentChecksumDesc" = "Se esperaba «%@»; se obtuvo «%@»"; "playapp.progress.canceled" = "Cancelado"; "button.Reload" = "Recargar"; "playapp.clearPlayChain" = "Borrar los datos de PlayChain"; @@ -389,32 +389,35 @@ "settings.toggle.introspection" = "Insertar bibliotecas de introspección"; "settings.toggle.introspection.help" = "Añade las bibliotecas de introspección del sistema a la aplicación. Se sabe que soluciona problemas con algunas aplicaciones que no se inician correctamente"; "settings.picker.scaler" = "Escalar la resolución"; -"button.Enable" = "Enable"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.masterPassword" = "Master Password"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"button.Enable" = "Activar"; +"button.Reset" = "Restablecer"; +"button.Unlock" = "Desbloquear"; +"settings.toggle.rootWorkDir" = "Iniciar la aplicación en el directorio raíz"; +"settings.toggle.rootWorkDir.help" = "Cambia el directorio de trabajo de la aplicación a / como en iOS. Si la aplicación no funciona correctamente, desactive esta función"; +"keycover.masterPassword" = "Contraseña maestra"; +"keycover.confirmMasterPassword" = "Confirmar la contraseña maestra"; +"keycover.oldMasterPassword" = "Contraseña maestra actual"; +"keycover.error.blankPassword" = "La contraseña no puede quedar vacía"; +"keycover.error.notMatch" = "Las contraseñas no coinciden"; +"keycover.error.incorrectPassword" = "Contraseña incorrecta"; +"keycover.status.title" = "Estado de KeyCover:"; +"keycover.status.managedPassword" = "Activado con la contraseña gestionada"; +"keycover.status.userPassword" = "Activado con la contraseña del usuario"; +"keycover.status.chainCount" = "Estado de la cadena KeyCover: "; +"keycover.status.unlockedCount %@ %@" = "%@ cadenas desbloqueadas en %@ total"; +"keycover.button.lockAll" = "Bloquear todas las cadenas"; +"keycover.button.changePassword" = "Cambiar la contraseña maestra"; +"keycover.toggle.startupPrompt" = "Solicitud de KeyCover al inicio"; +"keycover.toggle.startupPrompt.help" = "KeyCover le solicitará la contraseña maestra cuando se inicie la aplicación. Si se desactiva este comportamiento, se le solicitará cuando abra una aplicación que utilice PlayChain."; +"keycover.setup.useGeneratedKey" = "Gestión automática"; +"keycover.setup.useUserKey" = "Utilizar mi propia clave"; +"keycover.setup.encryptionKey" = "Clave de cifrado: "; +"keycover.setupPrompt.title" = "Introduce una contraseña maestra para KeyCover"; +"keycover.changePasswordPrompt.title" = "Ingresa tu contraseña maestra anterior y una nueva para actualizar tu clave de cifrado KeyCover"; +"keycover.removePrompt.title" = "Ingresa tu contraseña maestra para eliminar el cifrado KeyCover"; +"keycover.unlockPrompt.title" = "Ingresa tu contraseña maestra para desbloquear KeyCover"; +"keycover.alert.title" = "El llavero no estaba desbloqueado"; +"keycover.alert.content" = "Se ha desactivado el acceso al llavero para la sesión actual"; +"settings.toggle.autoKM" = "Mapa de teclas inteligente"; +"settings.toggle.autoKM.help" = "Desactivación automática de la asignación de las teclas cuando se detecta la entrada del texto"; +"settings.applicationCategoryType" = "Tipo de la aplicación"; diff --git a/PlayCover/fa.lproj/Localizable.strings b/PlayCover/fa.lproj/Localizable.strings index eae15c6a7..3faabc4b3 100644 --- a/PlayCover/fa.lproj/Localizable.strings +++ b/PlayCover/fa.lproj/Localizable.strings @@ -269,3 +269,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/fr.lproj/Localizable.strings b/PlayCover/fr.lproj/Localizable.strings index 1515deac8..72c7e560e 100644 --- a/PlayCover/fr.lproj/Localizable.strings +++ b/PlayCover/fr.lproj/Localizable.strings @@ -375,7 +375,7 @@ "playapp.progress.canceled" = "Annulé"; "ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; "playapp.clearPlayChain" = "Clear PlayChain Data"; -"playapp.importIPA" = "Import IPA"; +"playapp.importIPA" = "Importer un IPA"; "preferences.toggle.removePlayChain" = "Supprimer PlayChain"; "preferences.popover.duplicate" = "Duplicate Link"; "alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; @@ -418,3 +418,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/hi.lproj/Localizable.strings b/PlayCover/hi.lproj/Localizable.strings index 62b146b71..d656d3d72 100644 --- a/PlayCover/hi.lproj/Localizable.strings +++ b/PlayCover/hi.lproj/Localizable.strings @@ -261,3 +261,6 @@ "keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/id.lproj/Localizable.strings b/PlayCover/id.lproj/Localizable.strings index ff9080b95..9ecc4b092 100644 --- a/PlayCover/id.lproj/Localizable.strings +++ b/PlayCover/id.lproj/Localizable.strings @@ -298,7 +298,7 @@ "preferences.popover.badurl" = "URL tidak valid!"; "preferences.popover.badjson" = "JSON tidak valid atau tidak ditemukan!"; "preferences.textfield.url" = "Sumber URL..."; -"playapp.download.downloading" = "Menginstall..."; +"playapp.download.downloading" = "Mengunduh"; "error.waitDownload" = "Harap tunggu hingga unduhan selesai!"; "preferences.tab.uninstall" = "Hapus instalan"; "preferences.whenUninstalling" = "Ketika uninstall:"; @@ -324,10 +324,10 @@ "settings.info.playTools" = "PlayTools terpasang:"; "playapp.refreshSources" = "Menyegarkan sumber"; "error.appMaliciousProhibited" = "This App behaves maliciously on Macs, and using it can leave your device in an unbootable state, therefore it is blocked from PlayCover. (Uninstalling...)"; -"alert.install.injectPlayToolsQuestion" = "Do you want to inject PlayTools into this application?"; -"alert.install.playToolsInformative" = "PlayTools is a tool that allows you to bind keys to screen touches, custom display resolutions, and more, but it may break certain apps"; -"button.Help" = "Help"; -"button.Dismiss" = "Dismiss"; +"alert.install.injectPlayToolsQuestion" = "Apakah Anda ingin menyuntikkan PlayTools ke dalam aplikasi ini?"; +"alert.install.playToolsInformative" = "PlayTools adalah alat yang memungkinkan Anda untuk mengikat tombol ke sentuhan layar, resolusi tampilan khusus, dan banyak lagi, tetapi dapat merusak aplikasi tertentu"; +"button.Help" = "Bantuan"; +"button.Dismiss" = "Abaikan"; "state.enabled" = "Enabled"; "state.disabled" = "Disabled"; "configSigning.header" = "Configure Package Signing"; @@ -347,15 +347,15 @@ "configSigning.alert.info" = "Please paste and run the command in Terminal.app. Your Mac will reboot after"; "state.pendingReboot" = "Pending Reboot"; "menubar.configSigning" = "Configure Signing"; -"alert.power.title" = "Low Power Mode Enabled!"; -"alert.power.subtitle" = "Some apps will not work with Low Power Mode enabled. It is recommended to disable it."; -"ipaLibrary.version.older" = "This version is older than the one you have installed"; -"ipaLibrary.version.same" = "App already installed"; -"ipaLibrary.version.newer" = "This version is newer than the version you have installed"; -"ipaLibrary.alert.download" = "Are you sure you want to download this version of %@?"; -"ipaLibrary.download" = "Download"; -"alert.differentBundleIdKeymap.message" = "The keymap may have been created for another application."; -"alert.differentBundleIdKeymap.text" = "Are you sure you want to import this keymap?"; +"alert.power.title" = "Mode Daya Rendah Diaktifkan!"; +"alert.power.subtitle" = "Beberapa aplikasi tidak akan berfungsi dengan Mode Daya Rendah diaktifkan. Disarankan untuk menonaktifkannya."; +"ipaLibrary.version.older" = "Versi ini lebih tua dari versi yang telah Anda instal"; +"ipaLibrary.version.same" = "Aplikasi sudah diinstal"; +"ipaLibrary.version.newer" = "Versi ini lebih baru daripada versi yang telah Anda instal"; +"ipaLibrary.alert.download" = "Apakah Anda yakin ingin mengunduh versi %@ ini?"; +"ipaLibrary.download" = "Unduh"; +"alert.differentBundleIdKeymap.message" = "Keymap mungkin telah dibuat untuk aplikasi lain."; +"alert.differentBundleIdKeymap.text" = "Apakah Anda yakin ingin mengimpor keymap ini?"; "settings.text.debugger" = "Debugger:"; "settings.toggle.lldb" = "Open with LLDB"; "settings.toggle.lldbWithTerminal" = "Open in terminal"; @@ -364,32 +364,32 @@ "settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; "settings.playChain.debugging" = "PlayChain debugging"; "error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"playapp.noSources.title" = "Tidak ada IPA yang Diinstal"; +"playapp.noSources.subtitle" = "Saat ini Anda belum memiliki IPA yang terinstal. Klik tombol di bawah ini untuk mengimpornya."; "settings.tab.bypasses" = "Bypasses"; "settings.addToLaunchpad" = "Add to Launchpad"; "settings.removeFromLaunchpad" = "Remove from Launchpad"; -"playapp.download.integrityCheck" = "Verifying file integrity:"; -"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; -"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; -"playapp.progress.canceled" = "Canceled"; -"playapp.importIPA" = "Import IPA"; -"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; -"preferences.toggle.removePlayChain" = "Remove PlayChain"; -"preferences.popover.duplicate" = "Duplicate Link"; -"playapp.clearPlayChain" = "Clear PlayChain Data"; -"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; -"button.Reload" = "Reload"; +"playapp.download.integrityCheck" = "Memverifikasi integritas file:"; +"playapp.download.differentChecksum" = "Checksum yang berbeda! Apakah Anda ingin melanjutkan penginstalan?"; +"playapp.download.differentChecksumDesc" = "Diharapkan \"%@\", yang didapat adalah \"%@\""; +"playapp.progress.canceled" = "Dibatalkan"; +"playapp.importIPA" = "Impor IPA"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library membutuhkan koneksi internet"; +"preferences.toggle.removePlayChain" = "Hapus PlayChain"; +"preferences.popover.duplicate" = "Tautan Duplikat"; +"playapp.clearPlayChain" = "Bersihkan Data PlayChain"; +"alert.app.clearPlayChain" = "Semua data PlayChain akan dihapus. Anda mungkin perlu masuk ke aplikasi lagi. Apakah Anda ingin melanjutkan?"; +"button.Reload" = "Muat ulang"; "settings.highResolution" = "High resolution may cause crashing"; "settings.picker.windowFix" = "Fix window display issues"; "settings.picker.windowFixMethod.0" = "Normal"; "settings.picker.windowFixMethod.1" = "Alternate"; "settings.picker.windowFix.help" = "Apply window fixes that may helps your apps display normally"; -"preferences.popover.checking" = "Checking URL"; +"preferences.popover.checking" = "Memeriksa URL"; "settings.toggle.introspection" = "Insert Introspection libraries"; "settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; "settings.picker.scaler" = "Resolution Scaler"; -"button.Enable" = "Enable"; +"button.Enable" = "Aktifkan"; "button.Reset" = "Reset"; "button.Unlock" = "Unlock"; "settings.toggle.rootWorkDir" = "Start app at root directory"; @@ -418,3 +418,6 @@ "keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/ja.lproj/Localizable.strings b/PlayCover/ja.lproj/Localizable.strings index 43e3cc46d..6ddb15062 100644 --- a/PlayCover/ja.lproj/Localizable.strings +++ b/PlayCover/ja.lproj/Localizable.strings @@ -389,9 +389,9 @@ "settings.toggle.introspection" = "イントロスペクション ライブラリを挿入する"; "settings.toggle.introspection.help" = "システム イントロスペクション ライブラリをアプリに追加します。 一部のアプリが正しく起動しない問題を修正することが知られています"; "settings.picker.scaler" = "解像度スケーラー"; -"button.Enable" = "Enable"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; +"button.Enable" = "有効化"; +"button.Reset" = "リセット"; +"button.Unlock" = "ロック解除"; "settings.toggle.rootWorkDir" = "Start app at root directory"; "settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; "keycover.masterPassword" = "Master Password"; @@ -418,3 +418,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/ko.lproj/Localizable.strings b/PlayCover/ko.lproj/Localizable.strings index 14a04a5e3..bb957da49 100644 --- a/PlayCover/ko.lproj/Localizable.strings +++ b/PlayCover/ko.lproj/Localizable.strings @@ -1,20 +1,20 @@ /* (No Comment) */ -"alert.app.delete" = "모든 앱 데이터가 삭제됩니다. 앱 내부 파일들을 다시 다운로드해야 할 수도 있습니다. 정말로 진행하시겠습니까?"; +"alert.app.delete" = "모든 앱 데이터가 삭제됩니다. 앱 내부 파일을 다시 다운로드해야 할 수 있습니다. 정말로 진행하겠습니까?"; /* (No Comment) */ -"alert.app.preferences" = "모든 인앱 설정이 삭제됩니다. 정말로 진행하시겠습니까?"; +"alert.app.preferences" = "모든 인앱 설정이 삭제됩니다. 정말로 진행하겠습니까?"; /* (No Comment) */ -"alert.appCacheCleared" = "앱 데이터가 초기화 되었습니다!"; +"alert.appCacheCleared" = "앱 데이터가 지워졌습니다!"; /* (No Comment) */ "alert.error" = "오류가 발생했습니다!"; /* (No Comment) */ -"alert.errorImportKm" = "키매핑을 불러오는데 문제가 발생했습니다!"; +"alert.errorImportKm" = "키매핑을 가져오는 데 문제가 발생했습니다!"; /* (No Comment) */ -"alert.kmImported" = "키매핑을 불러왔습니다!"; +"alert.kmImported" = "키매핑을 가져왔습니다!"; /* (No Comment) */ "alert.moveAppToApplications.move" = "응용 프로그램 폴더로 이동하기"; @@ -53,7 +53,7 @@ "menubar.checkForUpdates" = "업데이트 확인..."; /* (No Comment) */ -"menubar.discord" = "디스코드"; +"menubar.discord" = "Discord"; /* (No Comment) */ "menubar.documentation" = "문서"; @@ -62,13 +62,13 @@ "menubar.exportToSideloady" = "Sideloadly로 내보내기"; /* (No Comment) */ -"menubar.github" = "깃허브"; +"menubar.github" = "GitHub"; /* (No Comment) */ "menubar.log.copy" = "로그 복사"; /* (No Comment) */ -"menubar.website" = "공식 홈페이지"; +"menubar.website" = "웹사이트"; /* (No Comment) */ "notification.appInstalled" = "앱이 설치되었습니다!"; @@ -80,13 +80,13 @@ "playapp.activateAccount" = "계정 전환하기"; /* (No Comment) */ -"playapp.clearCache" = "앱 데이터 초기화"; +"playapp.clearCache" = "앱 데이터 지우기"; /* (No Comment) */ -"playapp.clearPreferences" = "앱 설정 초기화"; +"playapp.clearPreferences" = "앱 설정 지우기"; /* (No Comment) */ -"playapp.delete" = "앱 삭제"; +"playapp.delete" = "앱 삭제하기"; /* (No Comment) */ "playapp.deleteAccount" = "계정 삭제하기"; @@ -95,13 +95,13 @@ "playapp.exportKm" = "키매핑 내보내기"; /* (No Comment) */ -"playapp.importKm" = "키매핑 불러오기"; +"playapp.importKm" = "키매핑 가져오기"; /* (No Comment) */ "playapp.install.addToLib" = "보관함에 앱을 추가하는 중..."; /* (No Comment) */ -"playapp.install.copy" = "앱 복사 중..."; +"playapp.install.copy" = "앱 복사하는 중..."; /* (No Comment) */ "playapp.install.createWrapper" = "앱 컨테이너 만드는 중..."; @@ -125,7 +125,7 @@ "playapp.settings" = "설정"; /* (No Comment) */ -"playapp.showInFinder" = "Finder에서 열기"; +"playapp.showInFinder" = "Finder에서 보기"; /* (No Comment) */ "playapp.storeCurrentAccount" = "계정 보관하기"; @@ -140,19 +140,19 @@ "preferences.toggle.automaticUpdates" = "자동으로 업데이트 확인"; /* (No Comment) */ -"settings.button.discord" = "사용자 지정 디스코드 활동 상태"; +"settings.button.discord" = "사용자 지정 Discord 활동 상태"; /* (No Comment) */ -"settings.button.clearActivity" = "사용자 지정 활동 상태 초기화"; +"settings.button.clearActivity" = "사용자 지정 활동 상태 지우기"; /* (No Comment) */ -"settings.picker.iosDevice" = "iOS 기종 선택:"; +"settings.picker.iosDevice" = "iOS 기기:"; /* %.f */ "settings.slider.mouseSensitivity" = "마우스 감도: %.f"; /* (No Comment) */ -"settings.text.applicationID" = "앱 ID"; +"settings.text.applicationID" = "애플리케이션 ID"; /* (No Comment) */ "settings.text.customHeight" = "높이"; @@ -179,28 +179,28 @@ "settings.text.state.help" = "제목 아래의 두 번째 줄"; /* (No Comment) */ -"settings.toggle.disableDisplaySleep" = "화면 잠자기 비활성화"; +"settings.toggle.disableDisplaySleep" = "화면 잠자기 사용 안 함"; /* (No Comment) */ -"settings.toggle.discord" = "디스코드 활동 상태 활성화"; +"settings.toggle.discord" = "Discord 활동 상태 사용"; /* (No Comment) */ -"settings.toggle.jbBypass" = "탈옥 우회 활성화 (Experimetal)"; +"settings.toggle.jbBypass" = "탈옥 우회 사용 (실험적)"; /* (No Comment) */ -"settings.toggle.km" = "키매핑 활성화"; +"settings.toggle.km" = "키매핑"; /* (No Comment) */ -"soundAlert.failureText" = "현재 출력 장치의 샘플 레이트를 48 kHz로 설정하는데 실패하였습니다. ‘오디오 MIDI 설정’ 앱에서 수동으로 샘플 레이트를 설정할 수 있습니다"; +"soundAlert.failureText" = "현재 출력 장치의 샘플 레이트를 48 kHz로 설정하지 못했습니다. ‘오디오 MIDI 설정’ 앱에서 수동으로 샘플 레이트를 설정할 수 있습니다"; /* (No Comment) */ -"soundAlert.informativeText" = "현재 출력 장치의 샘플 레이트가 44.1 또는 48 KHz가 아닙니다! 충돌이 발생할 수도 있습니다. 현재 출력장치의 샘플 레이트를 48 kHz로 설정하시겠어요?"; +"soundAlert.informativeText" = "현재 출력 장치의 샘플 레이트가 44.1 또는 48 KHz가 아닙니다! 충돌이 발생할 수 있습니다. 현재 출력 장치의 샘플 레이트를 48 kHz로 설정하겠습니까?"; /* (No Comment) */ "soundAlert.messageText" = "올바르지 않은 오디오 설정이 감지되었습니다!"; /* (No Comment) */ -"soundAlert.successText" = "현재 출력장치의 샘플 레이트를 48 kHz로 설정했습니다"; +"soundAlert.successText" = "현재 출력 장치의 샘플 레이트를 48 kHz로 설정했습니다"; /* (No Comment) */ "storeAccount.deleteAcc" = "계정 삭제하기"; @@ -238,53 +238,53 @@ "playapp.exportKmPanel.fieldLabel" = "PlayMap 이름:"; "sidebar.appLibrary" = "앱 보관함"; "sidebar.ipaLibrary" = "IPA 보관함"; -"storeAccount.alert.restoreAccount" = "정말로 계정을 복구하시겠습니까?"; +"storeAccount.alert.restoreAccount" = "정말로 계정을 복구하겠습니까?"; "storeAccount.alert.restoreAccount.button" = "계정 복구하기"; "storeAccount.alert.restoreAccount.msg" = "현재 로그인한 계정을 덮어씁니다."; -"storeAccount.alert.deleteAccount" = "정말로 계정을 삭제하시겠습니까?"; +"storeAccount.alert.deleteAccount" = "정말로 계정을 삭제하겠습니까?"; "storeAccount.alert.deleteAccount.button" = "계정 삭제하기"; "alert.moveAppToApplications.title" = "응용 프로그램 폴더로 이동할까요?"; -"alert.moveAppToApplications.subtitle" = "PlayCover는 올바르게 실행되려면 반드시 응용 프로그램 폴더에 있어야 합니다. PlayCover를 자동으로 이동하려면 아래 버튼을 누르세요."; +"alert.moveAppToApplications.subtitle" = "PlayCover가 올바르게 실행되려면 반드시 응용 프로그램 폴더에 있어야 합니다. PlayCover를 자동으로 이동하려면 아래 버튼을 누르세요."; "button.Quit" = "종료"; -"error.appEncrypted" = "이 앱은 암호화되어 있습니다! 복호화된 IPA를 사용해주세요. iMazing IPA는 지원되지 않습니다!"; -"error.appCorrupted" = "이 IPA에 문제가 발생했습니다. 다른 IPA를 사용해보세요."; -"error.appProhibited" = "PlayCover를 통해 이 앱을 사용하면 밴될 수 있습니다!"; -"error.noGenshinAccount" = "원신 계정을 찾을 수 없습니다! 앱 내 계정에 로그인하셨나요?"; +"error.appEncrypted" = "이 앱은 암호화되어 있습니다! 복호화된 IPA를 사용해 주세요. iMazing IPA는 지원되지 않습니다!"; +"error.appCorrupted" = "이 IPA에 문제가 발생했습니다. 다른 IPA를 사용해 보세요."; +"error.appProhibited" = "PlayCover를 통해 이 앱을 사용하면 차단될 수 있습니다!"; +"error.noGenshinAccount" = "원신 계정을 찾을 수 없습니다! 앱 내 계정에 로그인했습니까?"; "settings.tab.info" = "정보"; "settings.tab.km" = "키매핑"; -"settings.toggle.km.help" = "터치 전용 게임에 키보드 지원을 추가합니다. Command + K 키로 에디터 창을 열 수 있습니다."; +"settings.toggle.km.help" = "터치 전용 게임에 키보드 지원을 추가합니다. Command + K로 편집기 창을 열 수 있습니다."; "settings.tab.graphics" = "그래픽"; "settings.picker.adaptiveRes" = "해상도:"; -"settings.picker.adaptiveRes.help" = "앱 화면 해상도를 변경합니다"; +"settings.picker.adaptiveRes.help" = "앱 화면의 해상도를 변경합니다"; "settings.picker.adaptiveRes.0" = "앱 기본값"; "settings.picker.adaptiveRes.1" = "자동 (디스플레이 기반)"; "settings.picker.adaptiveRes.5" = "사용자화"; -"settings.picker.aspectRatio" = "가로세로 비율:"; -"settings.toggle.disableDisplaySleep.help" = "이 앱이 작동하는 중에 화면이 꺼지는 것을 방지합니다"; +"settings.picker.aspectRatio" = "화면비:"; +"settings.toggle.disableDisplaySleep.help" = "이 앱이 작동하는 중 화면이 꺼지는 것을 방지합니다"; "settings.toggle.jbBypass.help" = "일부 게임에서의 탈옥 감지를 우회하려고 시도합니다 (항상 작동이 보장되지는 않습니다)"; "settings.info.bundleName" = "번들 이름:"; "settings.info.bundleIdentifier" = "번들 식별자:"; "settings.info.executableName" = "실행 파일 이름:"; "settings.info.minimumOSVersion" = "최소 OS 버전:"; -"settings.info.url" = "경로:"; +"settings.info.url" = "위치:"; "settings.resetSettings" = "설정 초기화"; "settings.resetKm" = "키매핑 초기화"; "settings.resetSettingsCompleted" = "설정을 기본값으로 되돌렸습니다!"; -"settings.resetKmCompleted" = "키매핑이 재설정되었습니다!"; +"settings.resetKmCompleted" = "키매핑을 초기화했습니다!"; "settings.tab.misc" = "기타"; -"settings.toggle.hud" = "Metal HUD 활성화"; +"settings.toggle.hud" = "Metal HUD 사용"; "settings.info.bundleVersion" = "번들 버전:"; -"playapp.deleteConfirm" = "삭제"; -"playapp.deleteMessage" = "%@을(를) 삭제하시겠습니까?"; +"playapp.deleteConfirm" = "삭제하기"; +"playapp.deleteMessage" = "%@을(를) 삭제하겠습니까?"; "alert.legacyImport.title" = "레거시 앱 설정이 감지되었습니다!"; -"alert.legacyImport.subtitle" = "이전 버전의 설정과 키맵 파일이 존재합니다. 새로운 버전의 포맷으로 변환하시겠습니까?"; +"alert.legacyImport.subtitle" = "이전 버전의 설정과 키맵 파일이 존재합니다. 새 포맷으로 변환하겠습니까?"; "button.Convert" = "변환"; -"settings.info.displayName" = "보이는 제목:"; +"settings.info.displayName" = "표시 이름:"; "settings.text.detectedResolution" = "감지된 해상도:"; "playapp.add" = "앱 추가하기"; -"alert.wrongFileType.title" = "잘못된 파일 형식입니다!"; +"alert.wrongFileType.title" = "파일 형식 잘못됨!"; "alert.wrongFileType.subtitle" = "PlayCover는 유효한 .ipa 파일만 설치할 수 있습니다."; -"ipaLibrary.noSources.title" = "IPA 소스들이 추가되지 않았습니다"; +"ipaLibrary.noSources.title" = "추가된 IPA 소스 없음"; "ipaLibrary.noSources.button" = "소스 추가하기"; "playapp.addSource" = "소스 추가하기"; "ipaLibrary.noSources.subtitle" = "현재 어떠한 IPA 소스도 추가되지 않았습니다. 다음 버튼을 클릭하고 하나를 추가하세요."; @@ -302,119 +302,122 @@ "error.waitDownload" = "현재 다운로드가 끝날 때까지 기다려 주세요!"; "playapp.progress.failed" = "실패함"; "alert.supression" = "PlayCover 환경설정에서 변경할 수 있습니다"; -"preferences.toggle.clearAppData" = "데이터 초기화"; -"preferences.tab.uninstall" = "제거"; -"preferences.whenUninstalling" = "제거 할 때:"; +"preferences.toggle.clearAppData" = "데이터 지우기"; +"preferences.tab.uninstall" = "삭제"; +"preferences.whenUninstalling" = "삭제할 때:"; "preferences.toggle.showUninstall" = "경고 팝업 보기"; "preferences.toggle.removeKeymap" = "키맵 제거하기"; "preferences.toggle.removeSetting" = "설정 제거하기"; "preferences.toggle.removeEntitlements" = "권한 제거하기"; "preferences.button.pruneFiles" = "파일 정리"; -"preferences.prune.alert" = "모든 파일을 정리하시겠습니까?"; -"preferences.prune.message" = "이는 설정, 키매핑, 권한, 앱데이터를 포함한 모든 불필요한 것들을 제거합니다"; -"menubar.clearCache" = "캐시 제거"; -"preferences.tab.install" = "설치"; +"preferences.prune.alert" = "모든 파일을 정리하겠습니까?"; +"preferences.prune.message" = "설정, 키매핑, 자격 증명, 앱 데이터를 포함한 모든 불필요한 것을 제거합니다"; +"menubar.clearCache" = "캐시 지우기"; +"preferences.tab.install" = "설치하기"; "preferences.toggle.showInstallPopup" = "PlayTools 설치 팝업 보기"; "preferences.toggle.alwaysInstallPlayTools" = "항상 PlayTools 설치"; "alert.install.injectPlayTools" = "PlayTools 주입"; "button.Yes" = "예"; -"button.No" = "아니오"; -"settings.noPlayTools" = "이 앱에는 PlayTools 가 설치되지 않았습니다"; +"button.No" = "아니요"; +"settings.noPlayTools" = "이 앱에는 PlayTools가 설치되지 않았습니다"; "settings.removePlayTools" = "PlayTools 제거"; -"settings.info.playTools" = "PlayTools 설치 여부:"; -"playapp.refreshSources" = "소스 새로고침"; -"error.appMaliciousProhibited" = "이 앱은 Mac에서 악의적으로 작동하며 기기를 부팅할 수 없는 상태로 만들 수 있으므로 PlayCover에서 차단됩니다. (제거 중...)"; -"alert.install.injectPlayToolsQuestion" = "이 애플리케이션에 PlayTools를 주입하시겠습니까?"; -"alert.install.playToolsInformative" = "PlayTools는 화면 터치, 사용자 지정 디스플레이 해상도 등에 키를 바인딩할 수 있는 도구이지만 특정 앱이 중단될 수 있습니다"; +"settings.info.playTools" = "PlayTools 설치:"; +"playapp.refreshSources" = "소스 다시 로드"; +"error.appMaliciousProhibited" = "이 앱은 Mac에서 악의적으로 작동하며 기기를 부팅할 수 없는 상태로 만들 수 있으므로 PlayCover에서 차단됩니다. (삭제하는 중...)"; +"alert.install.injectPlayToolsQuestion" = "이 응용 프로그램에 PlayTools를 주입하겠습니까?"; +"alert.install.playToolsInformative" = "PlayTools는 화면 터치, 사용자 지정 디스플레이 해상도 등에 키를 바인딩할 수 있는 도구이지만 특정 앱에서 중단될 수 있습니다"; "state.pendingReboot" = "재시동 대기 중"; -"configSigning.info.SIP" = "AMFI를 끄려면 SIP을 완전히 비활성화해야 합니다."; -"configSigning.info.SIPHeader" = "시스템 무결성 보호(SIP)"; -"configSigning.info.AMFI" = "가짜 서명을 허용하여 앱을 올바른 팀 ID로 실행하기 위해서는 AMFI를 꺼야합니다"; -"configSigning.info.AMFIHeader" = "Apple 모바일 파일 무결성(AMFI)"; -"configSigning.action.shutdown" = "사용자의 Mac 종료"; -"configSigning.action.copyCommand" = "명령 복사하기"; -"configSigning.action.restart" = "사용자의 Mac 재시동"; -"configSigning.step.disableSIP" = "리커버리 모드에서 SIP를 비활성화 해주세요"; -"configSigning.step.disableAMFI" = "AMFI를 비활성화 해주세요"; -"configSigning.step.AMFIreboot" = "AMFI가 비활성화되었습니다. 재부팅 해주세요"; +"configSigning.info.SIP" = "AMFI를 끄려면 SIP를 완전히 종료해야 합니다."; +"configSigning.info.SIPHeader" = "시스템 무결성 보호 (SIP)"; +"configSigning.info.AMFI" = "가짜 서명을 허용하여 앱을 올바른 팀 ID로 실행하기 위해서는 AMFI를 종료해야 합니다"; +"configSigning.info.AMFIHeader" = "Apple 모바일 파일 무결성 (AMFI)"; +"configSigning.action.shutdown" = "내 Mac 종료"; +"configSigning.action.copyCommand" = "클립보드에 명령 복사하기"; +"configSigning.action.restart" = "내 Mac 재시동"; +"configSigning.step.disableSIP" = "복구 모드에서 SIP를 사용 해제해 주세요"; +"configSigning.step.disableAMFI" = "AMFI를 사용 해제해 주세요"; +"configSigning.step.AMFIreboot" = "AMFI가 사용 해제되었습니다. 재시동해 주세요"; "button.Help" = "도움말"; "button.Dismiss" = "닫기"; "state.enabled" = "사용"; "state.disabled" = "사용 안 함"; "menubar.configSigning" = "서명 구성"; "configSigning.header" = "패키지 서명 구성"; -"configSigning.subtext" = "패키지 서명은 인증 같은 작업을 위해 올바른 팀 ID를 필요로 하는 \n앱의 문제를 해결하는 데 도움이 됩니다. \n이 기능을 사용하도록 설정하면 보안 위험이 발생할 수도 있습니다.\n\n 따라서 필요하지 않다면 비활성화 하는 것이 좋습니다"; +"configSigning.subtext" = "패키지 서명은 인증 같은 작업을 위해 올바른 팀 ID를 필요로 하는 \n앱의 문제를 해결하는 데 도움이 됩니다. \n이 기능을 사용 설정하면 보안 위험이 발생할 수 있습니다.\n\n 따라서 필요하지 않다면 사용하지 않는 것이 좋습니다"; "configSigning.step.complete" = "패키지 서명을 성공적으로 구성했습니다"; "configSigning.alert.copied" = "명령이 복사되었습니다!"; -"configSigning.alert.info" = "Terminal.app에 명령을 붙여넣고 실행하세요. Mac이 재부팅됩니다"; +"configSigning.alert.info" = "Terminal.app에 명령을 붙여넣고 실행하세요. Mac이 재시동됩니다"; "alert.power.title" = "저전력 모드가 켜져 있습니다!"; -"alert.power.subtitle" = "몇몇 앱들은 저전력 모드가 켜져 있는 경우 작동하지 않을 수 있습니다. 저전력 모드를 끄는 것이 권장됩니다."; -"ipaLibrary.version.older" = "이 버전은 설치되어 있는 버전보다 구버전입니다"; -"ipaLibrary.version.same" = "앱이 이미 설치되어있습니다"; +"alert.power.subtitle" = "일부 앱은 저전력 모드가 켜져 있는 경우 작동하지 않을 수 있습니다. 저전력 모드를 끄는 것을 권장합니다."; +"ipaLibrary.version.older" = "이 버전은 설치되어 있는 버전보다 오래됐습니다"; +"ipaLibrary.version.same" = "앱이 이미 설치되어 있습니다"; "settings.text.debugger" = "디버거:"; -"settings.toggle.lldb" = "LLDB를 통해 열기"; +"settings.toggle.lldb" = "LLDB로 열기"; "settings.toggle.lldbWithTerminal" = "터미널에서 열기"; -"ipaLibrary.version.newer" = "이 버전은 이미 설치되어있는 버전보다 최신버전입니다"; -"ipaLibrary.alert.download" = "이 버전의 %@을 정말로 다운받으시겠습니까?"; +"ipaLibrary.version.newer" = "이 버전은 설치되어 있는 버전보다 최신입니다"; +"ipaLibrary.alert.download" = "이 버전의 %@을(를) 다운로드하겠습니까?"; "ipaLibrary.download" = "다운로드"; -"alert.differentBundleIdKeymap.message" = "이 키매핑은 다른 앱을 위해 만들어졌을수도 있습니다."; -"alert.differentBundleIdKeymap.text" = "정말로 이 키매핑을 불러오시겠습니까?"; +"alert.differentBundleIdKeymap.message" = "이 키매핑은 다른 앱을 위해 만들어졌을 수 있습니다."; +"alert.differentBundleIdKeymap.text" = "정말로 이 키매핑을 가져오겠습니까?"; "settings.unavailable.hud" = "Metal HUD를 사용할 수 없습니다"; -"error.failedToStripBinary" = "fat binary에서 ARM64 arch를 찾을 수 없습니다!"; +"error.failedToStripBinary" = "fat 바이너리에서 ARM64 아키텍처를 찾을 수 없습니다!"; "settings.playChain.debugging" = "PlayChain 디버깅"; -"settings.playChain.enable" = "PlayChain 활성화(실험적 기능)"; +"settings.playChain.enable" = "PlayChain 사용 (실험적)"; "settings.playChain.help" = "이 애플리케이션에 대한 PlayChain 지원을 활성화하여 Apple 키체인 서비스를 (부분적으로) 사용할 수 있도록 합니다"; -"playapp.noSources.title" = "설치된 IPA가 없음"; +"playapp.noSources.title" = "설치된 IPA 없음"; "playapp.noSources.subtitle" = "현재 설치된 IPA가 없습니다. 아래 버튼을 클릭하여 가져오세요."; "settings.tab.bypasses" = "우회"; -"settings.addToLaunchpad" = "런치패드에 추가"; -"settings.removeFromLaunchpad" = "런치패드에서 제거"; +"settings.addToLaunchpad" = "Launchpad에 추가하기"; +"settings.removeFromLaunchpad" = "Launchpad에서 제거하기"; "playapp.download.integrityCheck" = "파일 무결성 확인:"; -"playapp.download.differentChecksum" = "체크섬이 다릅니다! 설치를 계속하시겠습니까?"; -"playapp.download.differentChecksumDesc" = "\"%@\"가 아닌 \"%@\"을(를) 받았습니다"; +"playapp.download.differentChecksum" = "체크섬이 다릅니다! 설치를 계속하겠습니까?"; +"playapp.download.differentChecksumDesc" = "\"%@\"이(가) 아닌 \"%@\"을(를) 받았습니다"; "playapp.progress.canceled" = "취소됨"; -"playapp.clearPlayChain" = "PlayChain(플레이 체인) 데이터 초기화하기"; -"playapp.importIPA" = "IPA 불러오기"; +"playapp.clearPlayChain" = "PlayChain 데이터 지우기"; +"playapp.importIPA" = "IPA 가져오기"; "ipaLibrary.noNetworkConnection.required" = "IPA 라이브러리는 인터넷 연결이 필요합니다"; -"preferences.toggle.removePlayChain" = "PlayChain 제거"; -"preferences.popover.duplicate" = "링크 복사"; -"alert.app.clearPlayChain" = "모든 PlayChain 데이터가 지워집니다. 앱에 다시 로그인해야 할 수도 있습니다. 계속하시겠습니까?"; -"button.Reload" = "새로고침"; -"settings.highResolution" = "고해상도는 충돌을 야기할 수 있습니다"; -"settings.picker.windowFix" = "창 표시 문제 수정"; +"preferences.toggle.removePlayChain" = "PlayChain 제거하기"; +"preferences.popover.duplicate" = "링크 복사하기"; +"alert.app.clearPlayChain" = "모든 PlayChain 데이터가 지워집니다. 앱에 다시 로그인해야 할 수 있습니다. 계속하겠습니까?"; +"button.Reload" = "다시 로드"; +"settings.highResolution" = "높은 해상도는 충돌을 일으킬 수 있습니다"; +"settings.picker.windowFix" = "디스플레이 문제 수정"; "settings.picker.windowFix.help" = "앱이 정상적으로 표시되는 데 도움이 될 수 있는 창 수정 적용"; "settings.picker.windowFixMethod.0" = "기본"; -"settings.picker.windowFixMethod.1" = "Alternate"; -"settings.toggle.introspection" = "Insert Introspection libraries"; -"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; +"settings.picker.windowFixMethod.1" = "대체"; +"settings.toggle.introspection" = "내장 보관함 삽입"; +"settings.toggle.introspection.help" = "앱에 시스템 내장 라이브러리를 추가합니다. 일부 앱이 올바르게 시작되지 않는 문제를 해결할 수 있습니다"; "preferences.popover.checking" = "URL 검사"; "settings.picker.scaler" = "해상도"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"button.Enable" = "Enable"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.masterPassword" = "Master Password"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"keycover.button.lockAll" = "모든 체인 잠그기"; +"keycover.button.changePassword" = "마스터 암호 변경"; +"keycover.toggle.startupPrompt" = "KeyCover 시작 시 암호 묻기"; +"keycover.toggle.startupPrompt.help" = "KeyCover가 애플리케이션을 시작할 때 마스터 암호를 묻는 메시지를 표시합니다. 사용 해제하면 PlayChain을 사용하는 앱을 시작할 때 메시지가 표시됩니다."; +"keycover.setup.useGeneratedKey" = "자동으로 관리"; +"keycover.setup.useUserKey" = "내 키 사용"; +"button.Enable" = "사용"; +"button.Reset" = "초기화"; +"button.Unlock" = "잠금 해제"; +"settings.toggle.rootWorkDir" = "최상위 디렉토리에서 앱 시작"; +"settings.toggle.rootWorkDir.help" = "iOS에서와 마찬가지로 앱의 작업 디렉토리를 /로 변경합니다. 앱이 오작동할 경우 이 기능을 끄세요"; +"keycover.masterPassword" = "마스터 암호"; +"keycover.confirmMasterPassword" = "마스터 암호 확인"; +"keycover.oldMasterPassword" = "현재 마스터 암호"; +"keycover.error.blankPassword" = "암호는 비워둘 수 없습니다"; +"keycover.error.notMatch" = "암호가 일치하지 않습니다"; +"keycover.error.incorrectPassword" = "잘못된 암호"; +"keycover.status.title" = "KeyCover 상태:"; +"keycover.status.managedPassword" = "관리 암호로 사용 설정됨"; +"keycover.status.userPassword" = "사용자 암호로 사용 설정됨"; +"keycover.status.chainCount" = "KeyCover 체인 상태: "; +"keycover.status.unlockedCount %@ %@" = "잠금 해제된 체인 %@개 (총 %@개)"; +"keycover.setup.encryptionKey" = "암호화 키: "; +"keycover.setupPrompt.title" = "KeyCover에 사용할 마스터 암호를 입력하세요"; +"keycover.changePasswordPrompt.title" = "기존 마스터 암호와 새 암호를 입력하여 KeyCover 암호화 키를 업데이트하세요"; +"keycover.removePrompt.title" = "KeyCover 암호화를 제거하려면 마스터 암호를 입력하세요"; +"keycover.unlockPrompt.title" = "KeyCover를 잠금 해제하려면 마스터 암호를 입력하세요"; +"keycover.alert.title" = "Keychain이 잠금 해제되지 않았습니다"; +"keycover.alert.content" = "현재 세션의 Keychain 접근이 비활성화되었습니다"; +"settings.toggle.autoKM" = "키매핑 시작"; +"settings.toggle.autoKM.help" = "텍스트 입력이 감지되면 자동으로 키매핑 비활성화"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/pt-br.lproj/Localizable.strings b/PlayCover/pt-br.lproj/Localizable.strings index a2be0fc63..203cab2fd 100644 --- a/PlayCover/pt-br.lproj/Localizable.strings +++ b/PlayCover/pt-br.lproj/Localizable.strings @@ -241,7 +241,7 @@ "keycover.confirmMasterPassword" = "Confirm Master Password"; "keycover.oldMasterPassword" = "Current Master Password"; "keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; +"keycover.error.notMatch" = "Senhas não coincidem"; "keycover.error.incorrectPassword" = "Incorrect Password"; "keycover.status.title" = "KeyCover Status:"; "keycover.status.managedPassword" = "Enabled with Managed Password"; @@ -261,3 +261,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/ro.lproj/Localizable.strings b/PlayCover/ro.lproj/Localizable.strings index a55f91db0..27be3b55e 100644 --- a/PlayCover/ro.lproj/Localizable.strings +++ b/PlayCover/ro.lproj/Localizable.strings @@ -261,3 +261,6 @@ "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/ru.lproj/Localizable.strings b/PlayCover/ru.lproj/Localizable.strings index 933157c55..8803e1ea7 100644 --- a/PlayCover/ru.lproj/Localizable.strings +++ b/PlayCover/ru.lproj/Localizable.strings @@ -1,29 +1,29 @@ /* (No Comment) */ -"alert.app.delete" = "Все данные приложение будут удалены. Возможно, нужно будет повторно загрузить приложение. Вы хотите продолжить?"; +"alert.app.delete" = "Все данные приложение будут удалены. Возможно, вам надо будет повторно скачать приложение. Вы хотите продолжить?"; /* (No Comment) */ "alert.app.preferences" = "Все настройки в приложении будут удалены. Вы хотите продолжить?"; /* (No Comment) */ -"alert.appCacheCleared" = "Все данные приложения будут удалены!"; +"alert.appCacheCleared" = "Все данные приложения были удалены!"; /* (No Comment) */ "alert.error" = "Произошла ошибка!"; /* (No Comment) */ -"alert.errorImportKm" = "Произошла ошибка при импорте!"; +"alert.errorImportKm" = "Произошла ошибка при импортировании!"; /* (No Comment) */ "alert.kmImported" = "Раскладка клавиш импортирована!"; /* (No Comment) */ -"alert.moveAppToApplications.move" = "Переместить в Приложения"; +"alert.moveAppToApplications.move" = "Переместить в папку Приложения (Applications)"; /* (No Comment) */ "alert.restart" = "Пожалуйста перезапустите PlayCover."; /* (No Comment) */ -"alert.storeAccount.regionIsNotValid" = "Текущий аккаунт находится в другом регионе. Запустите игру, смените регион и пройдите через ворота, чтобы сохраниться. Затем попробуйте еще раз"; +"alert.storeAccount.regionIsNotValid" = "Текущий аккаунт находится в другом регионе. Запустите игру, смените регион, пройдите через ворота, чтобы сохранить изменения. Затем попробуйте еще раз"; /* (No Comment) */ "alert.success" = "Успешно"; @@ -38,7 +38,7 @@ "button.Install" = "Установить"; /* (No Comment) */ -"button.OK" = "OK"; +"button.OK" = "ОК"; /* (No Comment) */ "button.Proceed" = "Продолжить"; @@ -47,7 +47,7 @@ "error.corruptedIPA" = "Этот файл .ipa поврежден. Он не содержит файла «Info.plist»."; /* (No Comment) */ -"error.waitInstallation" = "Дождитесь завершения текущей установки!"; +"error.waitInstallation" = "Пожалуйста дождитесь завершения установки!"; /* (No Comment) */ "menubar.checkForUpdates" = "Проверить наличие обновлений..."; @@ -80,7 +80,7 @@ "playapp.activateAccount" = "Сменить аккаунт"; /* (No Comment) */ -"playapp.clearCache" = "Очистить Данные Приложения"; +"playapp.clearCache" = "Очистить данные приложения"; /* (No Comment) */ "playapp.clearPreferences" = "Очистить настройки приложения"; @@ -92,16 +92,16 @@ "playapp.deleteAccount" = "Удалить аккаунт"; /* (No Comment) */ -"playapp.exportKm" = "Экспортировать назначение ключей"; +"playapp.exportKm" = "Экспортировать раскладку"; /* (No Comment) */ -"playapp.importKm" = "Импортировать кеймаппинг"; +"playapp.importKm" = "Импортировать раскладку"; /* (No Comment) */ -"playapp.install.addToLib" = "Добавление приложения в библиотеку..."; +"playapp.install.addToLib" = "Приложения добавляется в библиотеку..."; /* (No Comment) */ -"playapp.install.copy" = "Копирование приложения..."; +"playapp.install.copy" = "Приложение копируется..."; /* (No Comment) */ "playapp.install.createWrapper" = "Создание оболочки приложения..."; @@ -122,7 +122,7 @@ "playapp.openCache" = "Открыть данные приложения"; /* (No Comment) */ -"playapp.settings" = "Настройки приложения"; +"playapp.settings" = "Настройки"; /* (No Comment) */ "playapp.showInFinder" = "Показать в Finder"; @@ -131,13 +131,13 @@ "playapp.storeCurrentAccount" = "Сохранить аккаунт"; /* (No Comment) */ -"preferences.button.checkForUpdates" = "Проверка наличия обновлений"; +"preferences.button.checkForUpdates" = "Проверить на наличие обновлений"; /* (No Comment) */ "preferences.tab.updates" = "Обновления"; /* (No Comment) */ -"preferences.toggle.automaticUpdates" = "Автоматическая проверка наличия обновлений"; +"preferences.toggle.automaticUpdates" = "Автоматическая проверка наличие обновлений"; /* (No Comment) */ "settings.button.discord" = "Пользовательская активность Discord"; @@ -149,19 +149,19 @@ "settings.picker.iosDevice" = "iOS устройство:"; /* %.f */ -"settings.slider.mouseSensitivity" = "Mouse sensitivity: %.f"; +"settings.slider.mouseSensitivity" = "Чувствительность мыши: %.f"; /* (No Comment) */ "settings.text.applicationID" = "ID Приложения"; /* (No Comment) */ -"settings.text.customHeight" = "Height"; +"settings.text.customHeight" = "Высота"; /* (No Comment) */ "settings.text.customWidth" = "Ширина"; /* (No Comment) */ -"settings.text.details" = "Подробности"; +"settings.text.details" = "Детали"; /* (No Comment) */ "settings.text.details.help" = "Первая строка под заголовком"; @@ -185,10 +185,10 @@ "settings.toggle.discord" = "Включить активность Discord"; /* (No Comment) */ -"settings.toggle.jbBypass" = "Включить обход Jailbreak (Alpha)"; +"settings.toggle.jbBypass" = "Включить обход Jailbreak (Экспериментально)"; /* (No Comment) */ -"settings.toggle.km" = "Включить кеймаппинг"; +"settings.toggle.km" = "Включить клавиатурную раскладку"; /* (No Comment) */ "soundAlert.failureText" = "Не удалось установить частоту дискретизации текущего устройства вывода на 48 кГц. Вы можете вручную установить частоту дискретизации в приложении Audio MIDI Setup"; @@ -221,7 +221,7 @@ "storeAccount.selectAccRegion.asia" = "Азия"; /* (No Comment) */ -"storeAccount.selectAccRegion.cht" = "TW, HK, MO"; +"storeAccount.selectAccRegion.cht" = "Тайвань, Гонконг, Макао"; /* (No Comment) */ "storeAccount.selectAccRegion.euro" = "Европа"; @@ -236,29 +236,29 @@ "storeAccount.storeAcc" = "Сохранить аккаунт"; "playapp.exportKmPanel.fieldLabel" = "Имя PlayMap:"; "sidebar.appLibrary" = "Библиотека приложений"; -"button.Quit" = "Выход"; -"storeAccount.alert.restoreAccount" = "Восстановить учетную запись?"; +"button.Quit" = "Выйти"; +"storeAccount.alert.restoreAccount" = "Вы хотите восстановить учетную запись?"; "storeAccount.alert.restoreAccount.button" = "Восстановить учетную запись"; "sidebar.ipaLibrary" = "Библиотека IPA"; -"storeAccount.alert.restoreAccount.msg" = "Это действие перезапишет учетную запись, в которой вы авторизованы сейчас."; +"storeAccount.alert.restoreAccount.msg" = "Данное действие выкинет вас из аккаунта, в которой вы сейчас авторизованы."; "storeAccount.alert.deleteAccount" = "Удалить учетную запись?"; "storeAccount.alert.deleteAccount.button" = "Удалить учетную запись"; "alert.moveAppToApplications.title" = "Переместить в папку Applications (Программы)?"; -"alert.moveAppToApplications.subtitle" = "Приложение PlayCover должно находиться в папке Applications (Программы), чтобы оно работало корректно. Нажмите на кнопку ниже, чтобы переместить PlayCover автоматически."; +"alert.moveAppToApplications.subtitle" = "Для корректной работы PlayCover должен находиться в папке Applications (Программы). Нажмите на кнопку ниже, чтобы переместить PlayCover автоматически."; "error.appEncrypted" = "Это приложение зашифровано! Пожалуйста, используйте расшифрованные файлы IPA. Файлы IPA из iMazing не поддерживаются!"; "error.appCorrupted" = "С данным IPA что-то пошло не так. Пожалуйста, попробуйте другой файл IPA."; "error.appProhibited" = "Использование этого приложения через PlayCover скорее всего приведет к бану!"; "error.noGenshinAccount" = "Мы не смогли найти аккаунт Genshin! Вы вошли в аккаунт внутри приложения?"; "settings.title" = "Настройки %@"; -"settings.tab.info" = "Инфо"; -"settings.tab.km" = "Кеймаппинг"; +"settings.tab.info" = "Информация"; +"settings.tab.km" = "Раскладка клавиатуры"; "settings.toggle.km.help" = "Добавить поддержку клавиатуры для игр только с тач-интерфейсом. Нажмите Command + K, чтобы открыть меню редактирования."; "settings.tab.graphics" = "Графика"; "settings.picker.adaptiveRes" = "Разрешение:"; "settings.picker.adaptiveRes.help" = "Меняет разрешение окна приложения"; -"settings.picker.adaptiveRes.0" = "По-умолчанию"; -"settings.picker.adaptiveRes.1" = "Авто (в зависимости от дисплея)"; -"settings.picker.adaptiveRes.5" = "Собственное"; +"settings.picker.adaptiveRes.0" = "По умолчанию"; +"settings.picker.adaptiveRes.1" = "Автоматически (в зависимости от разрешения дисплея)"; +"settings.picker.adaptiveRes.5" = "Пользовательское"; "settings.picker.aspectRatio" = "Соотношение сторон:"; "settings.resetKmCompleted" = "Кеймаппинг сброшен!"; "settings.toggle.disableDisplaySleep.help" = "Предотвращать выключение дисплея во время работы приложения"; @@ -278,10 +278,10 @@ "playapp.deleteConfirm" = "Удалить"; "playapp.deleteMessage" = "Вы уверены, что хотите удалить %@?"; "alert.legacyImport.title" = "Обнаружены настройки приложения из старой версии!"; -"alert.legacyImport.subtitle" = "Были обнаружены устаревшие настройки и файлы кеймаппингов. Хотели бы вы преобразовать эти файлы в новый формат?"; +"alert.legacyImport.subtitle" = "Были обнаружены устаревшие настройки и файлы раскладки клавиатуры. Хотели бы вы преобразовать эти файлы в новый формат?"; "button.Convert" = "Конвертировать"; "settings.text.detectedResolution" = "Обнаруженное разрешение:"; -"playapp.add" = "Установить приложение"; +"playapp.add" = "Добавить приложение"; "alert.wrongFileType.title" = "Неверный тип файла!"; "alert.wrongFileType.subtitle" = "PlayCover может установить только корректные .ipa файлы."; "playapp.addSource" = "Добавить источник"; @@ -295,37 +295,37 @@ "preferences.button.moveSourceUp" = "Переместить выше"; "preferences.button.moveSourceDown" = "Переместить ниже"; "preferences.popover.valid" = "Ссылка действительна"; -"preferences.popover.badurl" = "URL неверен!"; -"preferences.popover.badjson" = "Файл JSON неверен или не найден!"; -"preferences.textfield.url" = "URL источника..."; -"playapp.download.downloading" = "Скачивание..."; -"error.waitDownload" = "Пожалуйста, подождите окончания текущей загрузки!"; +"preferences.popover.badurl" = "URL-адрес недействителен!"; +"preferences.popover.badjson" = "Файл JSON недействителен или не найден!"; +"preferences.textfield.url" = "URL-адрес источника..."; +"playapp.download.downloading" = "Скачивание"; +"error.waitDownload" = "Пожалуйста дождитесь завершения загрузки!"; "preferences.tab.uninstall" = "Удалить"; "menubar.clearCache" = "Очистить кэш"; "preferences.whenUninstalling" = "При удалении:"; -"preferences.toggle.showUninstall" = "Отобразить всплывающее предупреждение"; +"preferences.toggle.showUninstall" = "Показывать всплывающее предупреждение"; "preferences.toggle.clearAppData" = "Очистить данные"; -"preferences.toggle.removeKeymap" = "Очистить кеймап"; -"preferences.toggle.removeSetting" = "Очистить настройки"; -"preferences.toggle.removeEntitlements" = "Очистить разрешения прав"; -"preferences.button.pruneFiles" = "Очистить файлы"; +"preferences.toggle.removeKeymap" = "Удалить раскладку"; +"preferences.toggle.removeSetting" = "Удалить настройки"; +"preferences.toggle.removeEntitlements" = "Забрать разрешения"; +"preferences.button.pruneFiles" = "Удалить файлы"; "preferences.prune.alert" = "Вы уверены, что хотите удалить все файлы?"; -"preferences.prune.message" = "Это действие удалит все неиспользуемые файлы, включая настройки, кеймаппы, разрешения прав и данные приложения"; +"preferences.prune.message" = "Данное действие удалит все не используемые файлы, включая настройки, раскладки, разрешения и данные приложения"; "playapp.progress.failed" = "Произошла ошибка"; "alert.supression" = "Вы можете изменить это в настройках PlayCover"; "alert.install.injectPlayTools" = "Внедрить PlayTools"; "button.Yes" = "Да"; "button.No" = "Нет"; -"preferences.tab.install" = "Установка"; -"preferences.toggle.showInstallPopup" = "Показывать запрос на установку PlayTools"; +"preferences.tab.install" = "Установить"; +"preferences.toggle.showInstallPopup" = "Показать окно установки PlayTools"; "preferences.toggle.alwaysInstallPlayTools" = "Всегда устанавливать PlayTools"; "settings.noPlayTools" = "PlayTools не установлены в этом приложении"; "settings.removePlayTools" = "Удалить PlayTools"; "settings.info.playTools" = "PlayTools установлен:"; "playapp.refreshSources" = "Обновить источники"; -"error.appMaliciousProhibited" = "Это приложение вредоносно для Mac. Используя его, вы можете привести свое устройство в незагружаемое состояние, поэтому оно заблокировано в PlayCover. (Удаление...)"; +"error.appMaliciousProhibited" = "Это приложение вредоносно для Mac. Используя его, вы можете привести свое устройство в незагружаемое состояние, поэтому оно заблокировано в PlayCover. (Удаляется...)"; "alert.install.injectPlayToolsQuestion" = "Вы хотите внедрить PlayTools в это приложение?"; -"alert.install.playToolsInformative" = "PlayTools – это инструмент, позволяющий связывать нажатия клавиш с жестами экрана, устанавливать собственное разрешение экрана и т.д., однако он может повредить некоторые приложения"; +"alert.install.playToolsInformative" = "PlayTools – это инструмент, позволяющий связывать нажатия клавиш с жестами экрана, устанавливать собственное разрешение экрана и т.д., однако он может нарушить корректную работу некоторых приложений"; "button.Help" = "Помощь"; "button.Dismiss" = "Закрыть"; "state.enabled" = "Включено"; @@ -347,74 +347,77 @@ "configSigning.step.complete" = "Подпись пакета была настроена успешно"; "configSigning.alert.copied" = "Команда скопирована!"; "configSigning.alert.info" = "Пожалуйста, вставьте и запустите команду в Terminal.app. Ваш Mac перезагрузится после"; -"alert.power.title" = "Режим энергосбережения включен!"; -"alert.power.subtitle" = "Некоторые приложения не будут работать, когда режим энергосбережения включён. Его рекомендуется отключить."; +"alert.power.title" = "Режим низкого энергопотребления включён!"; +"alert.power.subtitle" = "Некоторые приложения не будут работать, когда режим энергосбережения включён. Это рекомендуется отключить."; "ipaLibrary.download" = "Скачать"; -"alert.differentBundleIdKeymap.message" = "Кеймап, возможно, был создан для другого приложения."; +"alert.differentBundleIdKeymap.message" = "Данная клавиатурная раскладка, возможно, была создана для другого приложения."; "ipaLibrary.version.older" = "Эта версия старше установленной"; "ipaLibrary.version.same" = "Приложение уже установлено"; -"ipaLibrary.version.newer" = "Эта версия новее, чем версия, которую вы установили"; -"ipaLibrary.alert.download" = "Вы уверены что хотите установить версию %@?"; -"alert.differentBundleIdKeymap.text" = "Вы действительно хотите импортировать этот кеймап?"; +"ipaLibrary.version.newer" = "Эта версия является более новой, чем установленная"; +"ipaLibrary.alert.download" = "Вы уверены, что хотите установить версию %@?"; +"alert.differentBundleIdKeymap.text" = "Вы действительно хотите импортировать эту раскладку клавиатуры?"; "settings.text.debugger" = "Дебагер:"; "settings.toggle.lldb" = "Открыть с помощью LLDB"; "settings.toggle.lldbWithTerminal" = "Открыть в терминале"; "settings.unavailable.hud" = "Metal HUD недоступен"; -"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; -"settings.playChain.enable" = "Enable PlayChain (experimental)"; -"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; -"settings.playChain.debugging" = "PlayChain debugging"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; -"settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"playapp.download.integrityCheck" = "Verifying file integrity:"; -"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; -"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; -"playapp.progress.canceled" = "Canceled"; -"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; -"playapp.clearPlayChain" = "Clear PlayChain Data"; -"playapp.importIPA" = "Import IPA"; -"preferences.toggle.removePlayChain" = "Remove PlayChain"; -"preferences.popover.duplicate" = "Duplicate Link"; -"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; -"button.Reload" = "Reload"; -"settings.highResolution" = "High resolution may cause crashing"; -"settings.picker.windowFix" = "Fix window display issues"; -"settings.picker.windowFix.help" = "Apply window fixes that may helps your apps display normally"; -"settings.picker.windowFixMethod.0" = "Normal"; -"settings.picker.windowFixMethod.1" = "Alternate"; -"preferences.popover.checking" = "Checking URL"; -"settings.toggle.introspection" = "Insert Introspection libraries"; -"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; -"settings.picker.scaler" = "Resolution Scaler"; -"button.Enable" = "Enable"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"keycover.masterPassword" = "Master Password"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"error.failedToStripBinary" = "Не удалось найти исполняемый файл для ARM64 архитектуры!"; +"settings.playChain.enable" = "Включить PlayChain (Экспериментально)"; +"settings.playChain.help" = "Включить поддержку PlayChain для этого приложения, позволяя ему частично использовать сервисы Apple Keychain (связки ключей)"; +"settings.playChain.debugging" = "Откладка PlayChain"; +"playapp.noSources.title" = "IPA не установлены"; +"playapp.noSources.subtitle" = "Сейчас у вас нет установленных IPA. Нажмите на кнопку ниже для импорта."; +"settings.removeFromLaunchpad" = "Удалить из Launchpad"; +"settings.tab.bypasses" = "Обходы"; +"settings.addToLaunchpad" = "Добавить в Launchpad"; +"playapp.download.integrityCheck" = "Проверка целостности файлов:"; +"playapp.download.differentChecksum" = "Контрольные суммы не совпадают! Вы хотите продолжить установку?"; +"playapp.download.differentChecksumDesc" = "Ожидалось \"%@\", получено \"%@\""; +"playapp.progress.canceled" = "Отменена"; +"ipaLibrary.noNetworkConnection.required" = "IPA Библиотека требует интернет-соединение"; +"playapp.clearPlayChain" = "Очистить данные PlayChain"; +"playapp.importIPA" = "Импортировать IPA"; +"preferences.toggle.removePlayChain" = "Очистить PlayChain"; +"preferences.popover.duplicate" = "Дублирующая ссылка"; +"alert.app.clearPlayChain" = "Все данные PlayChain будут удалены. Возможно, вам придется снова проходить авторизацию в приложении. Вы хотите продолжить?"; +"button.Reload" = "Перезагрузить"; +"settings.highResolution" = "Высокое разрешение может вызвать сбой приложения"; +"settings.picker.windowFix" = "Исправить проблемы с отображением окна"; +"settings.picker.windowFix.help" = "Примените исправления окон, это может помочь вашим приложениям корректно отображаться"; +"settings.picker.windowFixMethod.0" = "Нормальный"; +"settings.picker.windowFixMethod.1" = "Альтернативный"; +"preferences.popover.checking" = "Проверка URL-адреса"; +"settings.toggle.introspection" = "Вставить библиотеки интроспекции"; +"settings.toggle.introspection.help" = "Добавить системные библиотеки интроспекции в приложение. Известно исправление проблем с некорректным запуском некоторых приложений"; +"settings.picker.scaler" = "Масштаб разрешения"; +"button.Enable" = "Включить"; +"settings.toggle.rootWorkDir.help" = "Изменить рабочий каталог приложения на / как на iOS. Отключите это в случае некорректной работы"; +"button.Reset" = "Сбросить"; +"button.Unlock" = "Разблокировать"; +"settings.toggle.rootWorkDir" = "Запустить приложение в корневой директории"; +"keycover.masterPassword" = "Мастер-пароль"; +"keycover.confirmMasterPassword" = "Потвердить мастер-пароль"; +"keycover.oldMasterPassword" = "Текущий мастер-пароль"; +"keycover.error.blankPassword" = "Пароль не может быть пустым"; +"keycover.error.notMatch" = "Пароли не совпадают друг с другом"; +"keycover.error.incorrectPassword" = "Неправильный пароль"; +"keycover.status.title" = "KeyCover статус:"; +"keycover.status.managedPassword" = "Включено с управляемым паролем"; +"keycover.status.userPassword" = "Включено с пользовательским паролем"; +"keycover.status.chainCount" = "KeyCover Chain статус: "; +"keycover.status.unlockedCount %@ %@" = "%@ разблокированных цепочек из %@ всего"; +"keycover.button.lockAll" = "Заблокировать все цепочки"; +"keycover.button.changePassword" = "Сменить мастер-пароль"; +"keycover.toggle.startupPrompt" = "Запрашивать KeyCover при запуске"; +"keycover.toggle.startupPrompt.help" = "KeyCover будет запрашивать ваш мастер-пароль при запуске этого приложения. Если отключено, тогда будет запрашиваться при запуске приложения, использующего PlayChain."; +"keycover.setup.useGeneratedKey" = "Управляется автоматически"; +"keycover.setup.useUserKey" = "Использовать мой собственный ключ"; +"keycover.setup.encryptionKey" = "Ключ шифрования: "; +"keycover.setupPrompt.title" = "Введите мастер-пароль, который будет использоваться для KeyCover"; +"keycover.changePasswordPrompt.title" = "Введите старый мастер-пароль и новый, чтобы обновить ваш ключ шифрования для KeyCover"; +"keycover.removePrompt.title" = "Введите мастер-пароль, чтобы убрать шифрование KeyCover"; +"keycover.unlockPrompt.title" = "Введите мастер-пароль, чтобы разблокировать KeyCover"; +"keycover.alert.title" = "Keychain не был разблокирован"; +"keycover.alert.content" = "Доступ к Keychain был отключен для текущей сессии"; +"settings.toggle.autoKM" = "Умная раскладка"; +"settings.toggle.autoKM.help" = "Автоматически выключать раскладку при вводе текста"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/tr.lproj/Localizable.strings b/PlayCover/tr.lproj/Localizable.strings index b1ded585c..7ee510ce6 100644 --- a/PlayCover/tr.lproj/Localizable.strings +++ b/PlayCover/tr.lproj/Localizable.strings @@ -1,20 +1,20 @@ "playapp.add" = "Uygulama ekle"; "playapp.addSource" = "Kaynak ekle"; "playapp.settings" = "Ayarlar"; -"playapp.showInFinder" = "Finder'da Göster"; +"playapp.showInFinder" = "Finder'de Göster"; "playapp.openCache" = "Uygulama Verisini Aç"; -"playapp.clearCache" = "Uygulama Verisini Kaldır"; -"playapp.importKm" = "Keymapping Ekle"; +"playapp.clearCache" = "Uygulama Verilerini Temizle"; +"playapp.importKm" = "Keymapping'i İçe Aktar"; "playapp.exportKm" = "Keymapping'i Dışarı Aktar"; "playapp.exportKmPanel.fieldLabel" = "PlayMap Adı:"; -"playapp.delete" = "Uygulamayı Sil"; -"playapp.deleteConfirm" = "Sil"; -"playapp.deleteMessage" = "%@'i silmek istediğinize emin misiniz?"; -"playapp.storeCurrentAccount" = "Hesap"; +"playapp.delete" = "Uygulamayı Kaldır"; +"playapp.deleteConfirm" = "Kaldır"; +"playapp.deleteMessage" = "%@'ı kaldırmak istediğinizden emin misiniz?"; +"playapp.storeCurrentAccount" = "Mağaza Hesabı"; "playapp.activateAccount" = "Hesap Değiştir"; "playapp.deleteAccount" = "Hesabı Sil"; "playapp.clearPreferences" = "Uygulama Tercihlerini Temizle"; -"playapp.refreshSources" = "Kaynak Yenile"; +"playapp.refreshSources" = "Kaynakları Yenile"; "ipaLibrary.noSources.title" = "IPA Kaynağı Yok"; "ipaLibrary.noSources.subtitle" = "IPA Kaynağı yok. Eklemek için aşağıya tıklıyın."; "ipaLibrary.noSources.button" = "Kaynak Ekle"; @@ -126,7 +126,7 @@ "settings.toggle.disableDisplaySleep" = "Ekran uyku modunu kapat"; "settings.toggle.disableDisplaySleep.help" = "Bu uygulama açıkken ekranın kararmasını önle"; "settings.noPlayTools" = "PlayTools bu uygulamada injekte edilmemiş"; -"settings.toggle.jbBypass" = "Jailbreak Korumasını Geç (Alfa)"; +"settings.toggle.jbBypass" = "Jailbreak Korumasını Geç (Deneysel)"; "settings.toggle.jbBypass.help" = "Bazı uygulamalardaki Jailbreak Korumasını geçmeye çalışır (Çalışma garantisi yok)"; "settings.removePlayTools" = "PlayTools'u çıkar"; "settings.info.displayName" = "Ekran adı:"; @@ -151,9 +151,9 @@ "menubar.checkForUpdates" = "Güncelleme Ara..."; "menubar.clearCache" = "Önbelleği temizle"; "soundAlert.messageText" = "Yanlış Ses Ayarları Bulundu!"; -"soundAlert.informativeText" = "Şu anki ses cihazınız 48 veya 44.1 KHz'yi desteklemiyor. Çökmeler yaşanabilir. Ses cihazınızın sample rate'ini 48KHz'ye değiştirmek istermisiniz?"; -"soundAlert.successText" = "48 KHz'ye ayarlandı"; -"soundAlert.failureText" = "48KHz'ye değiştirilmesinde bir hata çıktı. Audio MIDI uygulamasında manuel olarak değiştirebilirsiniz"; +"soundAlert.informativeText" = "Şu anki ses cihazınız 48 veya 44.1 kHz'yi desteklemiyor. Çökmeler yaşanabilir. Ses cihazınızın sample rate'ini 48kHz'ye değiştirmek istermisiniz?"; +"soundAlert.successText" = "48 kHz'ye ayarlandı"; +"soundAlert.failureText" = "48kHz'ye değiştirilmesinde bir hata çıktı. Audio MIDI uygulamasında manuel olarak değiştirebilirsiniz"; "settings.tab.misc" = "Öbür"; "settings.button.discord" = "Özelleştirilmiş Discord aktivitesi"; "settings.button.clearActivity" = "Özelleştirilmiş aktiviteyi sıfırla"; @@ -204,60 +204,63 @@ "settings.toggle.lldbWithTerminal" = "Terminal'de aç"; "settings.unavailable.hud" = "Metal HUD kullanım dışı"; "error.failedToStripBinary" = "Fat binary'de ARM64 arch bulunamadı!"; -"settings.playChain.enable" = "PlayChain'i aktive et (deneysel)"; +"settings.playChain.enable" = "PlayChain'i aktive et (Deneysel)"; "settings.playChain.help" = "Bu uygulamanın Apple Keychain Servislerini kullanması için PlayChain desteğini aç"; "settings.playChain.debugging" = "PlayChain debuglaması"; -"playapp.noSources.title" = "İndirilmiş IPA Yok"; -"playapp.noSources.subtitle" = "İndirilmiş IPA yok. Eklemek için aşağıya tıkla."; -"settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; -"playapp.download.integrityCheck" = "Verifying file integrity:"; -"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; -"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; -"playapp.progress.canceled" = "Canceled"; -"playapp.importIPA" = "IPA İndir"; +"playapp.noSources.title" = "Yüklü IPA Yok"; +"playapp.noSources.subtitle" = "İndirilmiş IPA yok. Eklemek için aşağıya tıklayınız."; +"settings.tab.bypasses" = "Baypaslar"; +"settings.addToLaunchpad" = "Launchpad'a Ekle"; +"settings.removeFromLaunchpad" = "Launchpad'dan Kaldır"; +"playapp.download.integrityCheck" = "Dosya bütünlüğü doğrulanıyor:"; +"playapp.download.differentChecksum" = "Farklı sağlama toplamları var! İndirmeye devam etmeği istiyor musunuz?"; +"playapp.download.differentChecksumDesc" = "Beklenen \"%@\", alınan \"%@\""; +"playapp.progress.canceled" = "İptal Edildi"; +"playapp.importIPA" = "IPA'yı İçe Aktar"; "preferences.toggle.removePlayChain" = "Playchain'i Kaldır"; -"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; -"playapp.clearPlayChain" = "Clear PlayChain Data"; +"alert.app.clearPlayChain" = "Bütün PlayChain datası silinecektir. Uygulamaya tekrar giriş yapmanız gerekebilir. Devam etmek istiyor musunuz?"; +"playapp.clearPlayChain" = "PlayChain Verilerini Temizle"; "ipaLibrary.noNetworkConnection.required" = "IPA Kütüphanesi için internet gereklidir"; -"preferences.popover.duplicate" = "Duplicate Link"; -"button.Reload" = "Reload"; -"settings.highResolution" = "High resolution may cause crashing"; -"settings.picker.windowFix" = "Fix window display issues"; -"settings.picker.windowFix.help" = "Apply window fixes that may helps your apps display normally"; +"preferences.popover.duplicate" = "Linki Çoğalt"; +"button.Reload" = "Tekrar Yükle"; +"settings.highResolution" = "Yüksek çözünürlük çökmelere sebep olabilir"; +"settings.picker.windowFix" = "Pencere sıkıntılarını onar"; +"settings.picker.windowFix.help" = "Uygulamalarınızın normal görünmesine yardımcı olabilecek pencere onarımlarını aktive et"; "settings.picker.windowFixMethod.0" = "Normal"; -"settings.picker.windowFixMethod.1" = "Alternate"; -"preferences.popover.checking" = "Checking URL"; -"settings.toggle.introspection" = "Insert Introspection libraries"; -"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; -"settings.picker.scaler" = "Resolution Scaler"; -"button.Enable" = "Enable"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.masterPassword" = "Master Password"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.picker.windowFixMethod.1" = "Alternatif"; +"preferences.popover.checking" = "URL Kontrol Ediliyor"; +"settings.toggle.introspection" = "Introspection kitaplıklarını içe aktar"; +"settings.toggle.introspection.help" = "Uygulamaya sistem iç gözlemi kitaplıkları ekle. Bazı uygulamaların açılmamasını onarabilir."; +"settings.picker.scaler" = "Çözünürlük Ölçekliyeci"; +"button.Enable" = "İzin Ver"; +"keycover.setup.useUserKey" = "Kendi anahtarımı kullan"; +"keycover.setup.encryptionKey" = "Şifreleme Anahtarı: "; +"keycover.setupPrompt.title" = "KeyCover için kullanılacak bir ana şifre girin."; +"keycover.changePasswordPrompt.title" = "KeyCover şifreleme anahtarınızı güncellemek için eski ana şifrenizi ve yeni bir ana şifre girin."; +"keycover.unlockPrompt.title" = "KeyCover'ın kilidini açmak için ana şifrenizi girin"; +"button.Reset" = "Resetle"; +"button.Unlock" = "Kilidi Aç"; +"settings.toggle.rootWorkDir" = "Uygulamayı kök dizinde başlat"; +"settings.toggle.rootWorkDir.help" = "Uygulamanın çalışan dizinini iOS'taki gibi /'e değiştir. Eğer uygulama garip davranırsa kapatınız."; +"keycover.masterPassword" = "Ana Şifre"; +"keycover.confirmMasterPassword" = "Ana Şifreyi Onayla"; +"keycover.oldMasterPassword" = "Şu anki Ana Şifre"; +"keycover.error.blankPassword" = "Şifre boş olamaz"; +"keycover.error.notMatch" = "Şifreler aynı değil"; +"keycover.error.incorrectPassword" = "Yanlış Şifre"; +"keycover.status.title" = "KeyCover Durumu:"; +"keycover.status.managedPassword" = "Yönetilen Şifre ile Açık"; +"keycover.status.userPassword" = "Kullanıcı Şifresi ile Açık"; +"keycover.status.chainCount" = "KeyCover Zincir Durumu: "; +"keycover.status.unlockedCount %@ %@" = "%@ tamdan %@ açık zincir"; +"keycover.button.lockAll" = "Bütün Zincirleri Kilitle"; +"keycover.button.changePassword" = "Ana Şifreyi Değiştir"; +"keycover.toggle.startupPrompt" = "Başlangıçta KeyCover için olan prompt"; +"keycover.toggle.startupPrompt.help" = "KeyCover uygulamayı açtığınızda ana şifrenizi isteyecektir. Eğer bu kapalıysa, PlayChain kullanan bir uygulamayı açtığınızda sorucaktır."; +"keycover.setup.useGeneratedKey" = "Otomatik Olarak Yönetildi"; +"keycover.removePrompt.title" = "KeyCover şifrelemesini kaldırmak için ana şifrenizi girin"; +"keycover.alert.title" = "Keychain açılmamıştır"; +"keycover.alert.content" = "Şu anki oturum için KeyChain erişimi kapatılmıştır"; +"settings.toggle.autoKM" = "Smart Keymap"; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.applicationCategoryType" = "Application Type"; diff --git a/PlayCover/vi.lproj/Localizable.strings b/PlayCover/vi.lproj/Localizable.strings index 399bfbfd6..4b0fcf79f 100644 --- a/PlayCover/vi.lproj/Localizable.strings +++ b/PlayCover/vi.lproj/Localizable.strings @@ -20,9 +20,9 @@ "storeAccount.selectAcc" = "Chọn một tài khoản"; "storeAccount.storeAcc" = "Lưu trữ tài khoản"; "storeAccount.deleteAcc" = "Xóa tài khoản"; -"playapp.install.unzip" = "Trích xuất ứng dụng từ tệp .ipa..."; -"playapp.install.createWrapper" = "Tạo trình bọc ứng dụng..."; -"playapp.install.installPlayTools" = "Cài đặt PlayTools..."; +"playapp.install.unzip" = "Đang trích xuất ứng dụng từ tệp .ipa..."; +"playapp.install.createWrapper" = "Đang tạo trình bọc ứng dụng..."; +"playapp.install.installPlayTools" = "Đang cài đặt PlayTools..."; "playapp.install.signing" = "Đang ký ứng dụng..."; "playapp.install.addToLib" = "Đang thêm vào thư viện..."; "playapp.install.copy" = "Đang sao chép ứng dụng..."; @@ -67,7 +67,7 @@ "settings.text.state.help" = "Hàng thứ hai bên dưới tiêu đề"; "settings.toggle.discord" = "Bật hoạt động tuỳ chỉnh cho Discord"; "menubar.log.copy" = "Sao chép nhật ký"; -"menubar.documentation" = "Tài liệu hướng dẫn"; +"menubar.documentation" = "Tài liệu (nhớ chuyển PlayCover về tiếng Anh cho tiện thao tác)"; "menubar.website" = "Website"; "menubar.github" = "GitHub"; "menubar.discord" = "Discord"; @@ -130,7 +130,7 @@ "alert.legacyImport.subtitle" = "Các thiết lập ứng dụng và bộ keymap cũ đã được phát hiện. Bạn có muốn chuyển đổi các tệp này sang định dạng mới không?"; "button.Convert" = "Chuyển đổi"; "playapp.deleteConfirm" = "Gỡ cài đặt"; -"playapp.deleteMessage" = "Bạn có chắc muốn gỡ cài đặt ứng dụng này không %@?"; +"playapp.deleteMessage" = "Bạn có chắc muốn gỡ cài đặt %@?"; "settings.text.detectedResolution" = "Độ phân giải được phát hiện:"; "alert.wrongFileType.subtitle" = "PlayCover chỉ có thể cài đặt các tệp .ipa hợp lệ."; "playapp.add" = "Thêm ứng dụng"; @@ -153,10 +153,10 @@ "error.waitDownload" = "Vui lòng đợi quá trình tải xuống hiện tại kết thúc!"; "preferences.prune.alert" = "Bạn muốn dọn dẹp tệp tin?"; "menubar.clearCache" = "Xóa bộ nhớ đệm"; -"preferences.tab.uninstall" = "Gỡ cào đặt"; +"preferences.tab.uninstall" = "Gỡ cài đặt"; "preferences.whenUninstalling" = "Khi gỡ cài đặt:"; "preferences.toggle.showUninstall" = "Hiện cửa sổ cảnh báo"; -"preferences.toggle.clearAppData" = "Xoá dữ liệu ứng"; +"preferences.toggle.clearAppData" = "Xoá dữ liệu ứng dụng"; "preferences.toggle.removeKeymap" = "Xoá keymap"; "preferences.toggle.removeSetting" = "Xoá thiết lập ứng dụng"; "preferences.toggle.removeEntitlements" = "Xoá quyền đã cấp"; @@ -205,7 +205,7 @@ "ipaLibrary.version.older" = "Phiên bản này cũ hơn phiên bản bạn đã cài đặt"; "ipaLibrary.version.same" = "Ứng dụng đã được cài đặt"; "ipaLibrary.version.newer" = "Phiên bản này mới hơn phiên bản bạn đã cài đặt"; -"ipaLibrary.alert.download" = "Bạn có chắc chắn muốn tải xuống phiên bản %@ này không?"; +"ipaLibrary.alert.download" = "Bạn có chắc chắn muốn tải xuống phiên bản %@?"; "ipaLibrary.download" = "Tải xuống"; "alert.differentBundleIdKeymap.message" = "Keymap này có thể đã được tạo cho một ứng dụng khác."; "alert.differentBundleIdKeymap.text" = "Bạn có chắc chắn muốn nhập keymap này không?"; @@ -216,7 +216,7 @@ "settings.playChain.enable" = "Kích hoạt PlayChain (Thử nghiệm)"; "settings.playChain.help" = "Sử dụng PlayChain cho ứng dụng này, cho phép nó sử dụng một phần các dịch vụ Apple Keychain"; "playapp.noSources.title" = "Chưa có ứng dụng nào"; -"playapp.noSources.subtitle" = "Hiện tại bạn chưa có ứng dụng nào cả. Click bên dưới để nhâp file IPA."; +"playapp.noSources.subtitle" = "Hiện tại bạn chưa có ứng dụng nào cả. Click bên dưới để nhập file IPA."; "settings.tab.bypasses" = "Bypass"; "settings.addToLaunchpad" = "Thêm vào Launchpad"; "settings.removeFromLaunchpad" = "Xóa khỏi Launchpad"; @@ -240,32 +240,35 @@ "settings.toggle.introspection" = "Chèn thư viện VMI"; "settings.toggle.introspection.help" = "Thêm thư viện nội quan hệ thống vào ứng dụng. Đã biết cách khắc phục sự cố với một số ứng dụng khởi động không đúng cách"; "settings.picker.scaler" = "Tỷ lệ độ phân giải"; -"button.Enable" = "Enable"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"keycover.masterPassword" = "Master Password"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"button.Enable" = "Bật"; +"button.Reset" = "Đặt lại"; +"button.Unlock" = "Mở khóa"; +"keycover.masterPassword" = "Mật khẩu chính"; +"settings.toggle.rootWorkDir" = "Bắt đầu ứng dụng tại thư mục gốc"; +"settings.toggle.rootWorkDir.help" = "Thay đổi thư mục làm việc của ứng dụng thành / giống như trên iOS. Tắt tùy chọn này nếu ứng dụng hoạt động sai"; +"keycover.confirmMasterPassword" = "Xác nhận mật khẩu chính"; +"keycover.oldMasterPassword" = "Mật khẩu chính hiện tại"; +"keycover.error.blankPassword" = "Mật khẩu không được để trống"; +"keycover.error.notMatch" = "Mật khẩu không khớp"; +"keycover.error.incorrectPassword" = "Mật khẩu không chính xác"; +"keycover.status.title" = "Trạng thái KeyCover:"; +"keycover.status.managedPassword" = "Được bật bằng Mật khẩu được quản lý"; +"keycover.status.userPassword" = "Được bật bằng Mật khẩu người dùng"; +"keycover.status.chainCount" = "Trạng thái chuỗi khoá KeyCover: "; +"keycover.status.unlockedCount %@ %@" = "%@ trong tổng số %@ chuỗi được mở khoá"; +"keycover.button.lockAll" = "Khóa tất cả các chuỗi"; +"keycover.button.changePassword" = "Thay đổi mật khẩu chính"; +"keycover.toggle.startupPrompt" = "Đặt lời nhắc cho KeyCover khi khởi động"; +"keycover.toggle.startupPrompt.help" = "KeyCover sẽ nhắc bạn nhập mật khẩu chính của bạn khi bạn khởi chạy ứng dụng. Nếu bị tắt, nó sẽ được nhắc khi bạn khởi chạy một ứng dụng sử dụng PlayChain."; +"keycover.setup.useGeneratedKey" = "Quản lý tự động"; +"keycover.setup.useUserKey" = "Sử dụng khóa riêng"; +"keycover.setup.encryptionKey" = "Khóa mã hóa: "; +"keycover.setupPrompt.title" = "Nhập mật khẩu chính để sử dụng cho KeyCover"; +"keycover.changePasswordPrompt.title" = "Nhập mật khẩu chính cũ và mật khẩu mới để cập nhật khóa mã hóa KeyCover"; +"keycover.removePrompt.title" = "Nhập mật khẩu chính của bạn để xóa mã hóa KeyCover"; +"keycover.unlockPrompt.title" = "Nhập mật khẩu chính của bạn để mở khóa KeyCover"; +"keycover.alert.title" = "Chuỗi khóa không được mở khóa"; +"keycover.alert.content" = "Truy cập chuỗi khóa đã bị vô hiệu hóa tại phiên hiện tại"; +"settings.toggle.autoKM" = "Keymap thông minh"; +"settings.toggle.autoKM.help" = "Tự động vô hiệu hóa keymapping khi phát hiện nhập văn bản"; +"settings.applicationCategoryType" = "Loại ứng dụng"; diff --git a/PlayCover/zh-Hans.lproj/Localizable.strings b/PlayCover/zh-Hans.lproj/Localizable.strings index 4f025c4b6..285be6eb0 100644 --- a/PlayCover/zh-Hans.lproj/Localizable.strings +++ b/PlayCover/zh-Hans.lproj/Localizable.strings @@ -393,7 +393,7 @@ "button.Enable" = "启用"; "button.Reset" = "重置"; "button.Unlock" = "解锁"; -"settings.toggle.rootWorkDir" = "在root目录启动应用程序"; +"settings.toggle.rootWorkDir" = "在 root 目录启动应用程序"; "settings.toggle.rootWorkDir.help" = "将应用程序的工作目录改为/,就像在iOS上一样。如果应用程序运行不正常,请关闭此功能"; "keycover.confirmMasterPassword" = "确认主密码"; "keycover.oldMasterPassword" = "当前主密码"; @@ -418,3 +418,6 @@ "keycover.unlockPrompt.title" = "输入您的主密码以解锁 KeyCover"; "keycover.alert.title" = "钥匙串未解锁"; "keycover.alert.content" = "当前会话已禁用钥匙串访问"; +"settings.toggle.autoKM" = "智能按键映射"; +"settings.toggle.autoKM.help" = "当检测到文本输入时自动禁用按键映射"; +"settings.applicationCategoryType" = "应用程序类型"; diff --git a/PlayCover/zh-Hant.lproj/Localizable.strings b/PlayCover/zh-Hant.lproj/Localizable.strings index 87784cb12..4ea8bd029 100644 --- a/PlayCover/zh-Hant.lproj/Localizable.strings +++ b/PlayCover/zh-Hant.lproj/Localizable.strings @@ -80,10 +80,10 @@ "playapp.activateAccount" = "切換帳號"; /* (No Comment) */ -"playapp.clearCache" = "清除應用程式數據"; +"playapp.clearCache" = "清除應用程式資料"; /* (No Comment) */ -"playapp.clearPreferences" = "清除應用偏好設置"; +"playapp.clearPreferences" = "清除應用程式偏好設定"; /* (No Comment) */ "playapp.delete" = "解除安裝應用程式"; @@ -119,13 +119,13 @@ "playapp.install.unzip" = "正在從文件中提取應用程式..."; /* (No Comment) */ -"playapp.openCache" = "顯示應用程式數據"; +"playapp.openCache" = "顯示應用程式資料"; /* (No Comment) */ "playapp.settings" = "偏好設定"; /* (No Comment) */ -"playapp.showInFinder" = "在Finder中查看"; +"playapp.showInFinder" = "在 Finder 中查看"; /* (No Comment) */ "playapp.storeCurrentAccount" = "保存現有帳號"; @@ -161,10 +161,10 @@ "settings.toggle.km" = "啟用鍵盤映射佈局"; /* (No Comment) */ -"soundAlert.failureText" = "未能成功更改現有音響設備取樣率為 48 KHz。您可以在 “音訊 MIDI 設定” 應用程式中手動設置"; +"soundAlert.failureText" = "未能成功更改現有音訊輸出設備取樣率為 48 KHz。您可以在 “音訊 MIDI 設定” 應用程式中自行手動設定"; /* (No Comment) */ -"soundAlert.informativeText" = "現有的音訊設備並無 48 或者 44.1 KHz 取樣率! 程式可能會崩潰。你希望把現有的音響設備設定成 48 KHz 取樣率嗎?"; +"soundAlert.informativeText" = "現有的音訊設備並無 48 或 44.1 KHz 取樣率! 程式可能會崩潰。你希望把現有的音響設備設定成 48 KHz 取樣率嗎?"; /* (No Comment) */ "soundAlert.messageText" = "檢測到聲音設定有問題!"; @@ -243,7 +243,7 @@ "settings.resetSettingsCompleted" = "偏好設定已被重置為預設值!"; "settings.resetKmCompleted" = "鍵盤映射佈局已被重置!"; "settings.tab.misc" = "雜項"; -"settings.button.discord" = "自定義Discord動態"; +"settings.button.discord" = "自訂 Discord 動態"; "settings.button.clearActivity" = "清除自定義動態"; "settings.text.applicationID" = "應用程式 ID"; "settings.text.details" = "詳細資料"; @@ -261,12 +261,12 @@ "alert.legacyImport.subtitle" = "檢測到舊版應用程式設置及鍵盤映射佈局。是否要把這些檔案轉換為新版格式?"; "button.Convert" = "轉換"; "settings.text.detectedResolution" = "檢測到的解析度:"; -"playapp.add" = "添加應用程式"; +"playapp.add" = "新增應用程式"; "alert.wrongFileType.title" = "錯誤的檔案類型!"; "alert.wrongFileType.subtitle" = "PlayCover 只可以安裝有效的 .ipa 檔案。"; "playapp.addSource" = "新增來源"; -"ipaLibrary.noSources.title" = "沒有新增 IPA 來源"; -"ipaLibrary.noSources.subtitle" = "您目前沒有新增IPA來源。點擊下面的按鈕來新增一個。"; +"ipaLibrary.noSources.title" = "尚未新增 IPA 來源"; +"ipaLibrary.noSources.subtitle" = "您目前沒有新增 IPA 來源。點擊下方的按鈕來新增一個。"; "ipaLibrary.noSources.button" = "新增來源"; "ipaLibrary.noNetworkConnection.toast" = "沒有網路連線!"; "preferences.tab.ipasource" = "IPA 來源"; @@ -292,7 +292,7 @@ "preferences.prune.message" = "這將刪除所有未使用的檔案,包括設定、鍵盤映射、授權和應用程式數據"; "playapp.progress.failed" = "失敗"; "alert.supression" = "你可以在 PlayCover 偏好設定中更改"; -"menubar.clearCache" = "清理緩存"; +"menubar.clearCache" = "清理快取"; "preferences.tab.install" = "安裝"; "preferences.toggle.showInstallPopup" = "顯示安裝 PlayTools 彈窗"; "preferences.toggle.alwaysInstallPlayTools" = "總是安裝 PlayTools"; @@ -302,7 +302,7 @@ "button.Yes" = "是"; "button.No" = "否"; "settings.noPlayTools" = "該應用程式沒有安裝PlayTools"; -"playapp.refreshSources" = "刷新來源"; +"playapp.refreshSources" = "重新整理來源"; "error.appMaliciousProhibited" = "此應用程式在 Mac 上存在惡意行為,使用它可能會使您的設備處於無法啟動的狀態,因此它會被 PlayCover 封鎖。 (正在解除安裝...)"; "alert.install.injectPlayToolsQuestion" = "你要在這個應用程序裡面植入 PlayTools 嗎?"; "alert.install.playToolsInformative" = "PlayTools是一個讓您將按鍵綁定到螢幕觸控,自定義顯示分辨率,和更多的工具,但它有可能會讓某些應用程序崩潰"; @@ -311,13 +311,13 @@ "state.enabled" = "啟用"; "state.disabled" = "禁用"; "state.pendingReboot" = "等待重啟"; -"menubar.configSigning" = "配置登錄"; +"menubar.configSigning" = "配置簽署"; "configSigning.header" = "配置應用程式包簽名"; "configSigning.subtext" = "應用程式包簽名幫助修復需要依靠正確 團隊 ID\n來處理身分驗證等操作的應用程序。\n這個功能有可能會帶來風險。\n\n因此,我們建議在不必要的情況下禁用它"; "configSigning.info.SIP" = "部分的 系統完整性保護(SIP)需要禁用,以便關閉 蘋果移動文件完整性(AMFI)."; "configSigning.info.SIPHeader" = "系統完整性保護"; "configSigning.info.AMFI" = "蘋果移動文件完整性(AMFI)需要關閉以允許應用程序假簽名,以便它們使用正確的 團隊ID 運行"; -"configSigning.info.AMFIHeader" = "蘋果移動文件完整性"; +"configSigning.info.AMFIHeader" = "蘋果移動檔案完整性(AMFI)"; "configSigning.action.shutdown" = "將我的 Mac 關機"; "configSigning.action.copyCommand" = "複製指令至剪貼板"; "configSigning.action.restart" = "將我的 Mac 重啟"; @@ -344,19 +344,19 @@ "error.failedToStripBinary" = "無法在通用二進制文件中檢索到 ARM64 架構!"; "settings.playChain.enable" = "啟用 PlayChain (試驗階段)"; "settings.playChain.help" = "在此應用程序啟用 PlayChain 將使應用程式(部分)使用 Apple Keychain 服務"; -"playapp.noSources.title" = "沒有安裝任何 IPA"; -"playapp.noSources.subtitle" = "暫時沒有安裝任何 IPA 文件。按下下面的按鈕來導入一個。"; -"settings.tab.bypasses" = "Bypasses"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"playapp.download.integrityCheck" = "Verifying file integrity:"; -"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; -"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; -"playapp.progress.canceled" = "Canceled"; +"playapp.noSources.title" = "尚未安裝任何 IPA"; +"playapp.noSources.subtitle" = "暫時沒有安裝任何 IPA 文件。點擊下方的按鈕來導入一個。"; +"settings.tab.bypasses" = "繞道"; +"settings.removeFromLaunchpad" = "自啟動台移除"; +"settings.addToLaunchpad" = "加入啟動台"; +"playapp.download.integrityCheck" = "驗證檔案的完整性:"; +"playapp.download.differentChecksum" = "checksum 不相符!是否繼續安裝?"; +"playapp.download.differentChecksumDesc" = "預期「%@」,得到「%@」"; +"playapp.progress.canceled" = "已取消"; "playapp.importIPA" = "導入 IPA"; "preferences.popover.duplicate" = "複製連結"; "button.Reload" = "刷新"; -"playapp.clearPlayChain" = "清除 PlayChain 數據"; +"playapp.clearPlayChain" = "清除 PlayChain 資料"; "ipaLibrary.noNetworkConnection.required" = "連接實際網路以查看 IPA Library"; "preferences.toggle.removePlayChain" = "移除 PlayChain"; "alert.app.clearPlayChain" = "所有 PlayChain 數據將被清除。您可能需要重新登錄應用程式。 您還希望繼續嗎?"; @@ -366,35 +366,38 @@ "settings.picker.windowFixMethod.0" = "正常"; "settings.picker.windowFixMethod.1" = "備用"; "preferences.popover.checking" = "檢查 URL"; -"settings.toggle.introspection" = "Insert Introspection libraries"; -"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; -"settings.picker.scaler" = "Resolution Scaler"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"keycover.masterPassword" = "Master Password"; -"keycover.button.changePassword" = "Change Master Password"; -"button.Enable" = "Enable"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"settings.toggle.introspection" = "插入內檢庫"; +"settings.toggle.introspection.help" = "將系統自檢庫增加到應用程式中。修復了應用程式不能正確啓動的一些已知問題"; +"settings.picker.scaler" = "解像度縮放器"; +"settings.toggle.rootWorkDir" = "在根目錄下啓動應用程式"; +"keycover.masterPassword" = "主密碼"; +"keycover.button.changePassword" = "更改主密碼"; +"button.Enable" = "啟用"; +"button.Reset" = "重設"; +"button.Unlock" = "解鎖"; +"settings.toggle.rootWorkDir.help" = "將應用程式的工作目錄改為/,就像在 iOS 上一樣。如果應用程式表現不正常,請將其關閉"; +"keycover.confirmMasterPassword" = "確認主密碼"; +"keycover.oldMasterPassword" = "目前主密碼"; +"keycover.error.blankPassword" = "密碼不能留空"; +"keycover.error.notMatch" = "密碼不符合"; +"keycover.error.incorrectPassword" = "密碼不正確"; +"keycover.status.title" = "KeyCover 狀態:"; +"keycover.status.managedPassword" = "已通過受管理密碼啓用"; +"keycover.status.userPassword" = "已通過使用者密碼啓用"; +"keycover.status.chainCount" = "KeyCover Chain 狀態: "; +"keycover.status.unlockedCount %@ %@" = "%@ 個已解鎖鏈(共 %@ 個)"; +"keycover.button.lockAll" = "鎖定所有鏈"; +"keycover.toggle.startupPrompt" = "啓動時提示使用 KeyCover"; +"keycover.toggle.startupPrompt.help" = "當你啓動應用程式時,KeyCover 會彈出視窗要求主密碼。如果停用這個功能,則當你啓動使用 PlayChain 的應用程式時才會彈出視窗。"; +"keycover.setup.useGeneratedKey" = "已自動管理"; +"keycover.setup.useUserKey" = "使用我自己的鑰匙"; +"keycover.setup.encryptionKey" = "加密密鑰: "; +"keycover.setupPrompt.title" = "輸入一個用於 KeyCover 的主密碼"; +"keycover.changePasswordPrompt.title" = "輸入你的舊主密碼和新密碼,以更新你的 KeyCover 加密密鑰"; +"keycover.removePrompt.title" = "輸入主密碼以刪除 KeyCover 加密"; +"keycover.unlockPrompt.title" = "輸入你的主密碼以解鎖 KeyCover"; +"keycover.alert.title" = "鑰匙圈未解鎖"; +"keycover.alert.content" = "已停用目前工作階段的密鑰圈存取"; +"settings.toggle.autoKM" = "智能按鍵映射"; +"settings.toggle.autoKM.help" = "當感應到文本輸入時,自動停用按鍵映射"; +"settings.applicationCategoryType" = "應用程式類型"; From 392e37d64094452586156a17bc27f15587e9be42 Mon Sep 17 00:00:00 2001 From: ytai <653297351@qq.com> Date: Sun, 10 Dec 2023 14:48:16 +0800 Subject: [PATCH 38/79] Fix "isOn" in scrollwhell (#1254) --- PlayCover/Views/AppSettingsView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index 0245752be..30f8b0dff 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -157,7 +157,7 @@ struct KeymappingView: View { .help("settings.toggle.autoKM.help") } HStack { - Toggle("settings.toggle.enableScrollWheel", isOn: $settings.settings.keymapping) + Toggle("settings.toggle.enableScrollWheel", isOn: $settings.settings.enableScrollWheel) .help("settings.toggle.enableScrollWheel.help") Spacer() } From 2224ca8d3537690edddf30a16c040e70d0c25d2b Mon Sep 17 00:00:00 2001 From: Ryu-ga <37541583+Ryu-ga@users.noreply.github.com> Date: Mon, 11 Dec 2023 03:32:31 +0900 Subject: [PATCH 39/79] Add support for some iOS Apps that cannot find iOS Frameworks. (#1195) Co-authored-by: Ryu-ga --- PlayCover/Model/PlayApp.swift | 17 +++++++++-------- PlayCover/Views/AppSettingsView.swift | 15 +++++++++++++-- PlayCover/en.lproj/Localizable.strings | 2 ++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index 6b9f8a2df..d5373d2be 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -213,17 +213,18 @@ class PlayApp: BaseApp { } } - func introspection(set: Bool? = nil) -> Bool { - if info.lsEnvironment["DYLD_LIBRARY_PATH"] == nil { - info.lsEnvironment["DYLD_LIBRARY_PATH"] = "" - } + static let introspection: String = "/usr/lib/system/introspection" + static let iosFrameworks: String = "/System/iOSSupport/System/Library/Frameworks" + + func changeDyldLibraryPath(set: Bool? = nil, path: String) -> Bool { + info.lsEnvironment["DYLD_LIBRARY_PATH"] = info.lsEnvironment["DYLD_LIBRARY_PATH"] ?? "" if let set = set { if set { - info.lsEnvironment["DYLD_LIBRARY_PATH"]? += "/usr/lib/system/introspection:" + info.lsEnvironment["DYLD_LIBRARY_PATH"]? += "\(path):" } else { info.lsEnvironment["DYLD_LIBRARY_PATH"] = info.lsEnvironment["DYLD_LIBRARY_PATH"]? - .replacingOccurrences(of: "/usr/lib/system/introspection:", with: "") + .replacingOccurrences(of: "\(path):", with: "") } do { @@ -233,11 +234,11 @@ class PlayApp: BaseApp { } } - guard let introspection = info.lsEnvironment["DYLD_LIBRARY_PATH"] else { + guard let result = info.lsEnvironment["DYLD_LIBRARY_PATH"] else { return false } - return introspection.contains("/usr/lib/system/introspection") + return result.contains(path) } func hasAlias() -> Bool { diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index 30f8b0dff..80d822d05 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -82,7 +82,8 @@ struct AppSettingsView: View { .disabled(!(hasPlayTools ?? true)) BypassesView(settings: $viewModel.settings, hasPlayTools: $hasPlayTools, - hasIntrospection: viewModel.app.introspection(), + hasIntrospection: viewModel.app.changeDyldLibraryPath(path: PlayApp.introspection), + hasIosFrameworks: viewModel.app.changeDyldLibraryPath(path: PlayApp.iosFrameworks), app: viewModel.app) .tabItem { Text("settings.tab.bypasses") @@ -450,6 +451,7 @@ struct BypassesView: View { @Binding var hasPlayTools: Bool? @State var hasIntrospection: Bool + @State var hasIosFrameworks: Bool var app: PlayApp @@ -477,11 +479,20 @@ struct BypassesView: View { .help("settings.toggle.introspection.help") Spacer() } + Spacer() + HStack { + Toggle("settings.toggle.iosFrameworks", isOn: $hasIosFrameworks) + .help("settings.toggle.iosFrameworks.help") + Spacer() + } } .padding() } .onChange(of: hasIntrospection) {_ in - _ = app.introspection(set: hasIntrospection) + _ = app.changeDyldLibraryPath(set: hasIntrospection, path: PlayApp.introspection) + } + .onChange(of: hasIosFrameworks) {_ in + _ = app.changeDyldLibraryPath(set: hasIosFrameworks, path: PlayApp.iosFrameworks) } } } diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index 17514b4e1..ed093a509 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -193,6 +193,8 @@ "settings.playChain.debugging" = "PlayChain debugging"; "settings.toggle.introspection" = "Insert Introspection libraries"; "settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; "settings.applicationCategoryType" = "Application Type"; "settings.removePlayTools" = "Remove PlayTools"; From 5c971648cd76f0091d4bb219f2f23ac683a4e244 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Mon, 11 Dec 2023 09:58:12 -0700 Subject: [PATCH 40/79] fix workflows --- .github/workflows/1.build_release.yml | 69 +++++-------------------- .github/workflows/2.nightly_release.yml | 50 ------------------ 2 files changed, 13 insertions(+), 106 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 283af5a80..c0dfb28af 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -3,10 +3,8 @@ on: push: tags: - "*" - env: CI: true - jobs: build: runs-on: macos-12 @@ -45,12 +43,16 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/PlayCover.dmg + mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg + env: + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Notarize DMG shell: bash run: | - fastlane notarize_dmg package:output/PlayCover.dmg + fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg + env: + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Clean Up shell: bash @@ -59,8 +61,10 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v3 with: - name: PlayCover.dmg - path: output/PlayCover.dmg + name: PlayCover_${{ env.TAG_NAME }}.dmg + path: output/PlayCover_${{ env.TAG_NAME }}.dmg + env: + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Release if: startsWith(github.ref, 'refs/tags/') @@ -68,53 +72,6 @@ jobs: with: draft: true files: | - output/PlayCover.dmg - - # manual release - # bump-sparkle: - # needs: build - # runs-on: macos-latest - # steps: - # - name: Checkout - # uses: actions/checkout@v3 - # with: - # ref: update # let me know if i should push to another branch - - # - name: Download Artifact - # uses: actions/download-artifact@v3.0.0 - # with: - # path: ./updates/ - - # - name: Download Sparkle Toolset - # run: | - # mkdir sparkle - # curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz - # tar -xf sparkle.tar.xz -C sparkle - - # - name: Update appcast.xml - # run: | - # echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast --channel stable \ - # --download-url-prefix 'https://github.com/PlayCover/PlayCover/releases/download/${{ env.TAG_NAME }}/' \ - # --link 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ - # --full-release-notes-url 'https://github.com/PlayCover/PlayCover/releases/tag/${{ env.TAG_NAME }}' \ - # -o appcast.xml \ - # ./updates --ed-key-file - - # env: - # TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} - - # - name: Cleanup tmp files - # run: | - # rm -rf sparkle/ - # rm sparkle.tar.xz - - # - name: Commit changes - # run: | - # git add appcast.xml - # git config --local user.email "$GITHUB_EMAIL" - # git config --local user.name "$GITHUB_USERNAME" - # git commit -m "chore: add release ${{ env.TAG_NAME }}" -a - # git push - # env: - # GITHUB_USERNAME: github-actions[bot] - # GITHUB_EMAIL: actions@github.com - # TAG_NAME: ${{ needs.build.outputs.TAG_NAME }} + output/PlayCover_${{ env.TAG_NAME }}.dmg + env: + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index df96234e5..1115daa64 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -3,9 +3,6 @@ on: workflow_dispatch: schedule: - cron: "30 19 * * *" - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - env: CI: true jobs: @@ -64,50 +61,3 @@ jobs: with: name: PlayCover_nightly_${{ github.run_number }}.dmg path: output/PlayCover_nightly_${{ github.run_number }}.dmg - - # manual release - # bump-sparkle: - # needs: build - # runs-on: macos-latest - # steps: - # - name: Checkout - # uses: actions/checkout@v2 - # with: - # repository: Playcover/playcover-website - # ref: gh-pages # let me know if i should push to another branch - - # - name: Download Artifact - # uses: actions/download-artifact@v3.0.0 - # with: - # path: ./updates/ - - # - name: Download Sparkle Toolset - # run: | - # mkdir sparkle - # curl -L "https://github.com/sparkle-project/Sparkle/releases/download/2.2.1/Sparkle-2.2.1.tar.xz" -o sparkle.tar.xz - # tar -xf sparkle.tar.xz -C sparkle - - # - name: Update appcast.xml - # run: | - # echo ${{ secrets.SPARKLE_KEY }} | ./sparkle/bin/generate_appcast ./updates --channel nightly --ed-key-file - - - # - name: Cleanup tmp files - # run: | - # rm -rf sparkle/ - # rm sparkle.tar.xz - - # - name: Commit changes - # run: | - # git add . - # git config --local user.email "$GITHUB_EMAIL" - # git config --local user.name "$GITHUB_USERNAME" - # git commit -m "chore: push update to sparkle" -a - # env: - # GITHUB_USERNAME: github-actions[bot] - # GITHUB_EMAIL: actions@github.com - - # - name: Push changes on Website - # uses: ad-m/github-push-action@master - # with: - # github_token: ${{ secrets.WEBSITE_PAT }} - # branch: gh-pages # let me know if i should push to another branch From 6d226d565e3ea14f20a095b6bd24adba9b380c0f Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:03:44 -0700 Subject: [PATCH 41/79] Chore/sync branch (#1261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add sparkle updat push to CI * add workflow_dispatch to the build actions * fix: wait until build job is done to start sparkle job * fix: invalid yaml structure * fix: invalid yaml structure * load config from .config * fix swift lint * Better clear app preferences error checking * improve appcast * update updater setting * disable CI for appcast * correct appcast url * remove nightly update channel * fix user customized config * Update Cartfile * PlayTools v2.0.7 * Bugfix release 2.0.4 * Translations update from Hosted Weblate (#747) * Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ca/ Translation: PlayCover/PlayCover * Translated using Weblate (Russian) Currently translated at 96.2% (206 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Indonesian) Currently translated at 78.9% (169 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 97.1% (208 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 97.1% (208 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 78.9% (169 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Turkish) Currently translated at 96.7% (207 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (German) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (German) Currently translated at 100.0% (212 of 212 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Spanish) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (Vietnamese) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Vietnamese) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: Trần Thanh Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (212 of 212 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: weng weng Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 99.0% (212 of 214 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 99.0% (212 of 214 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover --------- Co-authored-by: SkyrilHD Co-authored-by: gallegonovato Co-authored-by: Trần Thanh Co-authored-by: weng weng Co-authored-by: Araide * Adds toggle to fix screen issues with some apps in adaptive mode (#781) * Adding toggle to fix screen issues with some apps in adaptive mode * Fix pre 13.2 test * Adding macOS Version to app plist * Window fix toggle available for any setting up to 13.1 This fixes responsive for certain apps * Remove macOSVersion * change url scheme to apple-magnifier * feat: high resolution warning (#802) * feat: (slightly) more robust uri handler (#538) * feat: (slightly) more robust URI Handler * fix: behavior tweaks * chore: undo Cartfile.resolved changes * fix: use host instead of path for uri parsing * chore: remove print statement * fix: even tighter checks * Translations update from Hosted Weblate (#803) * Translated using Weblate (Russian) Currently translated at 86.0% (198 of 230 strings) Translated using Weblate (Russian) Currently translated at 86.4% (198 of 229 strings) Translated using Weblate (Russian) Currently translated at 87.2% (198 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Indonesian) Currently translated at 70.4% (162 of 230 strings) Translated using Weblate (Indonesian) Currently translated at 70.7% (162 of 229 strings) Translated using Weblate (Indonesian) Currently translated at 71.3% (162 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 94.3% (217 of 230 strings) Translated using Weblate (Japanese) Currently translated at 86.9% (200 of 230 strings) Translated using Weblate (Japanese) Currently translated at 87.3% (200 of 229 strings) Translated using Weblate (Japanese) Currently translated at 88.1% (200 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: ささ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 88.2% (203 of 230 strings) Translated using Weblate (Korean) Currently translated at 88.6% (203 of 229 strings) Translated using Weblate (Korean) Currently translated at 89.4% (203 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 88.2% (203 of 230 strings) Translated using Weblate (Persian) Currently translated at 88.6% (203 of 229 strings) Translated using Weblate (Persian) Currently translated at 89.4% (203 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 70.4% (162 of 230 strings) Translated using Weblate (Romanian) Currently translated at 70.7% (162 of 229 strings) Translated using Weblate (Romanian) Currently translated at 71.3% (162 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 230 strings) Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 229 strings) Translated using Weblate (Catalan) Currently translated at 0.0% (0 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ca/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover * Translated using Weblate (Turkish) Currently translated at 89.1% (205 of 230 strings) Translated using Weblate (Turkish) Currently translated at 89.5% (205 of 229 strings) Translated using Weblate (Turkish) Currently translated at 90.3% (205 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 86.9% (200 of 230 strings) Translated using Weblate (Hindi) Currently translated at 87.3% (200 of 229 strings) Translated using Weblate (Hindi) Currently translated at 88.1% (200 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 86.5% (199 of 230 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 86.8% (199 of 229 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 87.6% (199 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Spanish) Currently translated at 99.5% (229 of 230 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (229 of 229 strings) Translated using Weblate (Spanish) Currently translated at 99.1% (227 of 229 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (227 of 227 strings) Translated using Weblate (Spanish) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (German) Currently translated at 99.5% (229 of 230 strings) Translated using Weblate (German) Currently translated at 100.0% (229 of 229 strings) Translated using Weblate (German) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (German) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Vietnamese) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Vietnamese) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Vietnamese) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (230 of 230 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Araide Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 95.6% (220 of 230 strings) Translated using Weblate (French) Currently translated at 96.0% (220 of 229 strings) Translated using Weblate (French) Currently translated at 96.9% (220 of 227 strings) Co-authored-by: Anonymous Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover --------- Co-authored-by: ささ Co-authored-by: Araide Co-authored-by: gallegonovato Co-authored-by: SkyrilHD * fix: deselect app on uninstall (#792) * fix version control mark in jp localization strings * PlayTools v2.1.0 * Bug fix release 2.0.5 * change inject cmdType for inject 1.1.0 * fix workflows --------- Co-authored-by: Candygoblen123 Co-authored-by: lucas lee Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> Co-authored-by: Depal1 <47154119+Depal1@users.noreply.github.com> Co-authored-by: José Moreno <47700212+JoseMoreville@users.noreply.github.com> Co-authored-by: Weblate (bot) Co-authored-by: SkyrilHD Co-authored-by: gallegonovato Co-authored-by: Trần Thanh Co-authored-by: weng weng Co-authored-by: Araide Co-authored-by: OHaiiBuzzle <23693150+ohaiibuzzle@users.noreply.github.com> Co-authored-by: ささ Co-authored-by: Xyct <87l46110@gmail.com> --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index 3c108d7c7..41d8c74bf 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "PlayCover/PlayTools" "3.0.0-staging" +github "PlayCover/PlayTools" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index 3c108d7c7..db246e4db 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "PlayCover/PlayTools" "3.0.0-staging" +github "PlayCover/PlayTools" "v3.0.0-beta.2" From f58c7393be94dfeb44d2c837eda95df517b52fa1 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Tue, 12 Dec 2023 09:31:53 -0700 Subject: [PATCH 42/79] Update issue templates (#1264) * update pc and mac versions in bug template * add pc and mac version in app+game template --- .github/ISSUE_TEMPLATE/APP-SUPPORT.yml | 22 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/BUG-REPORT.yml | 3 +++ .github/ISSUE_TEMPLATE/GAME-SUPPORT.yml | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml index df813103e..740ece628 100644 --- a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml @@ -34,6 +34,28 @@ body: label: Crash log description: Copy and paste in any relevant crash logs in plain text. render: shell + - type: dropdown + id: pc-version + attributes: + label: What version of PlayCover are you using? + options: + - Nightly/beta + - 2.0.4 + - 2.0.5 + - 3.0.0 + validations: + required: true + - type: dropdown + id: mac-version + attributes: + label: What version of macOS are you using? + options: + - "Monterey (macOS 12)" + - "Ventura (macOS 13)" + - "Sonoma (macOS 14)" + - macOS beta (please state the specific version) + validations: + required: true - type: checkboxes attributes: label: Issue Language diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml index a1b451b38..975f63cf7 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -37,6 +37,8 @@ body: options: - Nightly/beta - 2.0.4 + - 2.0.5 + - 3.0.0 validations: required: true - type: dropdown @@ -46,6 +48,7 @@ body: options: - "Monterey (macOS 12)" - "Ventura (macOS 13)" + - "Sonoma (macOS 14)" - macOS beta (please state the specific version) validations: required: true diff --git a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml index 8fbbf630e..b04e7415d 100644 --- a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml @@ -34,6 +34,28 @@ body: label: Crash log description: Copy and paste in any relevant crash logs in plain text. render: shell + - type: dropdown + id: pc-version + attributes: + label: What version of PlayCover are you using? + options: + - Nightly/beta + - 2.0.4 + - 2.0.5 + - 3.0.0 + validations: + required: true + - type: dropdown + id: mac-version + attributes: + label: What version of macOS are you using? + options: + - "Monterey (macOS 12)" + - "Ventura (macOS 13)" + - "Sonoma (macOS 14)" + - macOS beta (please state the specific version) + validations: + required: true - type: checkboxes attributes: label: Issue Language From bcb9ad8fb24a67f9e3c7465c3f35e1f2035fa082 Mon Sep 17 00:00:00 2001 From: zanderp25 Date: Tue, 12 Dec 2023 11:52:55 -0500 Subject: [PATCH 43/79] Add catch-all to BUG-REPORT.yml and add 3.0.0 beta 2 (#1265) * Add catch-all to BUG-REPORT.yml * Add 3.0.0 b2 to BUG-REPORT.yml --- .github/ISSUE_TEMPLATE/BUG-REPORT.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml index 975f63cf7..2a63e7f77 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -35,10 +35,12 @@ body: attributes: label: What version of PlayCover are you using? options: - - Nightly/beta - - 2.0.4 + - "3.0.0 beta 2" + - "3.0.0 beta 1" - 2.0.5 - - 3.0.0 + - 2.0.4 + - "Nightly/beta (please specify build number)" + - "Other (please specify)" validations: required: true - type: dropdown @@ -46,10 +48,11 @@ body: attributes: label: What version of macOS are you using? options: - - "Monterey (macOS 12)" - - "Ventura (macOS 13)" - "Sonoma (macOS 14)" - - macOS beta (please state the specific version) + - "Ventura (macOS 13)" + - "Monterey (macOS 12)" + - "macOS beta (please state the specific version)" + - "Other (please specify)" validations: required: true - type: checkboxes From 08548e895b6d718549078c8f270763ecce34ae2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:15:38 +0000 Subject: [PATCH 44/79] Update 1.build_release.yml (#1266) --- .github/workflows/1.build_release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index c0dfb28af..ddad70cba 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -1,5 +1,6 @@ name: Build & Release macOS App on: + workflow_dispatch: push: tags: - "*" From 5e67f78161c1d2bb8894308b8c923e95ae869e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:16:43 +0000 Subject: [PATCH 45/79] Update 1.build_release.yml (#1266) (#1267) --- .github/workflows/1.build_release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index c0dfb28af..ddad70cba 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -1,5 +1,6 @@ name: Build & Release macOS App on: + workflow_dispatch: push: tags: - "*" From ff6f6cbf14516518a3ebd0204d57c2006a9c7dee Mon Sep 17 00:00:00 2001 From: Xyct <87l46110@gmail.com> Date: Wed, 13 Dec 2023 01:59:08 +0800 Subject: [PATCH 46/79] Add catch-all options to APP- and GAME-SUPPORT and append chip models to README (#1268) * Add chip models to README.md * Add catch-all options to APP- and GAME-SUPPORT --- .github/ISSUE_TEMPLATE/APP-SUPPORT.yml | 15 +++++++++------ .github/ISSUE_TEMPLATE/GAME-SUPPORT.yml | 15 +++++++++------ README.md | 6 ++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml index 740ece628..6308102d5 100644 --- a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml @@ -39,10 +39,12 @@ body: attributes: label: What version of PlayCover are you using? options: - - Nightly/beta - - 2.0.4 + - "3.0.0 beta 2" + - "3.0.0 beta 1" - 2.0.5 - - 3.0.0 + - 2.0.4 + - "Nightly/beta (please specify build number)" + - "Other (please specify)" validations: required: true - type: dropdown @@ -50,10 +52,11 @@ body: attributes: label: What version of macOS are you using? options: - - "Monterey (macOS 12)" - - "Ventura (macOS 13)" - "Sonoma (macOS 14)" - - macOS beta (please state the specific version) + - "Ventura (macOS 13)" + - "Monterey (macOS 12)" + - "macOS beta (please state the specific version)" + - "Other (please specify)" validations: required: true - type: checkboxes diff --git a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml index b04e7415d..30761dd21 100644 --- a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml @@ -39,10 +39,12 @@ body: attributes: label: What version of PlayCover are you using? options: - - Nightly/beta - - 2.0.4 + - "3.0.0 beta 2" + - "3.0.0 beta 1" - 2.0.5 - - 3.0.0 + - 2.0.4 + - "Nightly/beta (please specify build number)" + - "Other (please specify)" validations: required: true - type: dropdown @@ -50,10 +52,11 @@ body: attributes: label: What version of macOS are you using? options: - - "Monterey (macOS 12)" - - "Ventura (macOS 13)" - "Sonoma (macOS 14)" - - macOS beta (please state the specific version) + - "Ventura (macOS 13)" + - "Monterey (macOS 12)" + - "macOS beta (please state the specific version)" + - "Other (please specify)" validations: required: true - type: checkboxes diff --git a/README.md b/README.md index b152f8003..c060b33cd 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,12 @@ At the moment, PlayCover can only run on Apple Silicon Macs. Devices with the fo * M1 Max * M1 Ultra * M2 +* M2 Pro +* M2 Max +* M2 Ultra +* M3 +* M3 Pro +* M3 Max If you have an Intel Mac, you can explore alternatives like Bootcamp or emulators. From c0937af75593133e414daef40a95d0a4bbc8da2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:59:41 +0000 Subject: [PATCH 47/79] Adding develop changes to stable (#1269) * Update 1.build_release.yml (#1266) * Add catch-all options to APP- and GAME-SUPPORT and append chip models to README (#1268) * Add chip models to README.md * Add catch-all options to APP- and GAME-SUPPORT --------- Co-authored-by: Xyct <87l46110@gmail.com> --- .github/ISSUE_TEMPLATE/APP-SUPPORT.yml | 15 +++++++++------ .github/ISSUE_TEMPLATE/GAME-SUPPORT.yml | 15 +++++++++------ README.md | 6 ++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml index 740ece628..6308102d5 100644 --- a/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/APP-SUPPORT.yml @@ -39,10 +39,12 @@ body: attributes: label: What version of PlayCover are you using? options: - - Nightly/beta - - 2.0.4 + - "3.0.0 beta 2" + - "3.0.0 beta 1" - 2.0.5 - - 3.0.0 + - 2.0.4 + - "Nightly/beta (please specify build number)" + - "Other (please specify)" validations: required: true - type: dropdown @@ -50,10 +52,11 @@ body: attributes: label: What version of macOS are you using? options: - - "Monterey (macOS 12)" - - "Ventura (macOS 13)" - "Sonoma (macOS 14)" - - macOS beta (please state the specific version) + - "Ventura (macOS 13)" + - "Monterey (macOS 12)" + - "macOS beta (please state the specific version)" + - "Other (please specify)" validations: required: true - type: checkboxes diff --git a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml index b04e7415d..30761dd21 100644 --- a/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml +++ b/.github/ISSUE_TEMPLATE/GAME-SUPPORT.yml @@ -39,10 +39,12 @@ body: attributes: label: What version of PlayCover are you using? options: - - Nightly/beta - - 2.0.4 + - "3.0.0 beta 2" + - "3.0.0 beta 1" - 2.0.5 - - 3.0.0 + - 2.0.4 + - "Nightly/beta (please specify build number)" + - "Other (please specify)" validations: required: true - type: dropdown @@ -50,10 +52,11 @@ body: attributes: label: What version of macOS are you using? options: - - "Monterey (macOS 12)" - - "Ventura (macOS 13)" - "Sonoma (macOS 14)" - - macOS beta (please state the specific version) + - "Ventura (macOS 13)" + - "Monterey (macOS 12)" + - "macOS beta (please state the specific version)" + - "Other (please specify)" validations: required: true - type: checkboxes diff --git a/README.md b/README.md index b152f8003..c060b33cd 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,12 @@ At the moment, PlayCover can only run on Apple Silicon Macs. Devices with the fo * M1 Max * M1 Ultra * M2 +* M2 Pro +* M2 Max +* M2 Ultra +* M3 +* M3 Pro +* M3 Max If you have an Intel Mac, you can explore alternatives like Bootcamp or emulators. From 98bbf8a5ce0ee30e75d9e6d99deea798fbeeccab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:13:12 +0000 Subject: [PATCH 48/79] Update 1.build_release.yml --- .github/workflows/1.build_release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index ddad70cba..98274b481 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -1,6 +1,8 @@ name: Build & Release macOS App on: workflow_dispatch: + tags: + - "*" push: tags: - "*" From e1700b587b5be3bfa24fca5981c711869a26c12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:14:50 +0000 Subject: [PATCH 49/79] Updating ymls (#1270) * Update 1.build_release.yml (#1266) * Add catch-all options to APP- and GAME-SUPPORT and append chip models to README (#1268) * Add chip models to README.md * Add catch-all options to APP- and GAME-SUPPORT * Update 1.build_release.yml --------- Co-authored-by: Xyct <87l46110@gmail.com> --- .github/workflows/1.build_release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index ddad70cba..98274b481 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -1,6 +1,8 @@ name: Build & Release macOS App on: workflow_dispatch: + tags: + - "*" push: tags: - "*" From 61b21b394be5c2e003d3c529adcca85fb6fc7553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:32:52 +0000 Subject: [PATCH 50/79] Update 1.build_release.yml --- .github/workflows/1.build_release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 98274b481..c2a5f6402 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -17,7 +17,7 @@ jobs: - name: Get the version id: tag_version - run: echo ::set-output name=TAG_NAME::${GITHUB_REF/refs\/tags\//} + run: echo ::set-output name=TAG_NAME::PlayCover_3.0.0rc2 - name: Install dependencies shell: bash @@ -46,9 +46,9 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg + mv ./output/*.dmg ./output/PlayCover_3.0.0rc2.dmg env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + TAG_NAME: PlayCover_3.0.0rc2 - name: Notarize DMG shell: bash From b0d814e9eec21e522362dfef6ca5442d77ba6598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:33:39 +0000 Subject: [PATCH 51/79] Updating yml (#1271) * Update 1.build_release.yml (#1266) * Add catch-all options to APP- and GAME-SUPPORT and append chip models to README (#1268) * Add chip models to README.md * Add catch-all options to APP- and GAME-SUPPORT * Update 1.build_release.yml * Update 1.build_release.yml --------- Co-authored-by: Xyct <87l46110@gmail.com> --- .github/workflows/1.build_release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 98274b481..c2a5f6402 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -17,7 +17,7 @@ jobs: - name: Get the version id: tag_version - run: echo ::set-output name=TAG_NAME::${GITHUB_REF/refs\/tags\//} + run: echo ::set-output name=TAG_NAME::PlayCover_3.0.0rc2 - name: Install dependencies shell: bash @@ -46,9 +46,9 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg + mv ./output/*.dmg ./output/PlayCover_3.0.0rc2.dmg env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + TAG_NAME: PlayCover_3.0.0rc2 - name: Notarize DMG shell: bash From 6dd92da9681d92efce13e0628798822332cd7541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Moreno?= <47700212+JoseMoreville@users.noreply.github.com> Date: Fri, 15 Dec 2023 11:57:52 +0000 Subject: [PATCH 52/79] Update 1.build_release.yml --- .github/workflows/1.build_release.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index c2a5f6402..669edc3cc 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -49,13 +49,14 @@ jobs: mv ./output/*.dmg ./output/PlayCover_3.0.0rc2.dmg env: TAG_NAME: PlayCover_3.0.0rc2 - - - name: Notarize DMG - shell: bash - run: | - fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + + # Will bring back with new settings to bring notorization back + # - name: Notarize DMG + # shell: bash + # run: | + # fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg + # env: + # TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - name: Clean Up shell: bash From eb455b358f84544ffe6531470403256427ab6f21 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:47:43 -0700 Subject: [PATCH 53/79] fix file name (#1285) --- .github/workflows/1.build_release.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 669edc3cc..38e78810b 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -46,9 +46,9 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/PlayCover_3.0.0rc2.dmg + mv ./output/*.dmg ./output/${{ env.TAG_NAME }}.dmg env: - TAG_NAME: PlayCover_3.0.0rc2 + TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} # Will bring back with new settings to bring notorization back # - name: Notarize DMG @@ -65,8 +65,8 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v3 with: - name: PlayCover_${{ env.TAG_NAME }}.dmg - path: output/PlayCover_${{ env.TAG_NAME }}.dmg + name: ${{ env.TAG_NAME }}.dmg + path: output/${{ env.TAG_NAME }}.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} @@ -76,6 +76,6 @@ jobs: with: draft: true files: | - output/PlayCover_${{ env.TAG_NAME }}.dmg + output/${{ env.TAG_NAME }}.dmg env: TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} From 0f9e0ef6ecbd2090d3f718f646ef27a6d7c79ce0 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Thu, 21 Dec 2023 22:34:48 -0700 Subject: [PATCH 54/79] revert build file + fix deprecation (#1288) * revert build file + fix deprecation * add back installs --- .github/workflows/1.build_release.yml | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 38e78810b..33407e8d0 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -17,7 +17,7 @@ jobs: - name: Get the version id: tag_version - run: echo ::set-output name=TAG_NAME::PlayCover_3.0.0rc2 + run: echo "TAG_NAME=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - name: Install dependencies shell: bash @@ -46,11 +46,9 @@ jobs: shell: bash run: | create-dmg ./output/PlayCover.app ./output - mv ./output/*.dmg ./output/${{ env.TAG_NAME }}.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} - - # Will bring back with new settings to bring notorization back + mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg + + # Will bring back when codesign id is updated # - name: Notarize DMG # shell: bash # run: | @@ -65,10 +63,8 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v3 with: - name: ${{ env.TAG_NAME }}.dmg - path: output/${{ env.TAG_NAME }}.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + name: PlayCover_${{ env.TAG_NAME }}.dmg + path: output/PlayCover_${{ env.TAG_NAME }}.dmg - name: Release if: startsWith(github.ref, 'refs/tags/') @@ -76,6 +72,4 @@ jobs: with: draft: true files: | - output/${{ env.TAG_NAME }}.dmg - env: - TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + output/PlayCover_${{ env.TAG_NAME }}.dmg From 9eb2eedfb5e4610149e52ef6ae5f176312dca55a Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 17 Jan 2024 22:35:25 +0900 Subject: [PATCH 55/79] fix xcode archive shows in "Other items" --- PlayCover.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index fd746ea0d..1cd233697 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -787,7 +787,7 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = NO; - RUN_DOCUMENTATION_COMPILER = YES; + RUN_DOCUMENTATION_COMPILER = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off; @@ -828,7 +828,7 @@ PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Direct io.playcover.PlayCover macos"; - RUN_DOCUMENTATION_COMPILER = YES; + RUN_DOCUMENTATION_COMPILER = NO; SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off; SWIFT_OBJC_BRIDGING_HEADER = "./PlayCover/PlayCover-Bridging-Header.h"; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "./PlayCover/PlayCover-Bridging-Header.h"; @@ -890,7 +890,7 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = NO; - RUN_DOCUMENTATION_COMPILER = YES; + RUN_DOCUMENTATION_COMPILER = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off; @@ -931,7 +931,7 @@ PRODUCT_BUNDLE_IDENTIFIER = io.playcover.PlayCover; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Direct io.playcover.PlayCover macos"; - RUN_DOCUMENTATION_COMPILER = YES; + RUN_DOCUMENTATION_COMPILER = NO; SWIFT_ENFORCE_EXCLUSIVE_ACCESS = off; SWIFT_OBJC_BRIDGING_HEADER = "./PlayCover/PlayCover-Bridging-Header.h"; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "./PlayCover/PlayCover-Bridging-Header.h"; From e223612c4477b314a378ede1bca763b3f85d8509 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 29 Jan 2024 12:32:15 +0800 Subject: [PATCH 56/79] Fix: solve nightly release warning in Action (#1346) * fix: update action & artifact version * chore: update checkout version. * chore: update checkout & artifact version. --- .github/workflows/1.build_release.yml | 4 ++-- .github/workflows/2.nightly_release.yml | 4 ++-- .github/workflows/SwiftLint.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 33407e8d0..3a180536f 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -13,7 +13,7 @@ jobs: runs-on: macos-12 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.0 - name: Get the version id: tag_version @@ -61,7 +61,7 @@ jobs: run: rm apikey.json - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.3.0 with: name: PlayCover_${{ env.TAG_NAME }}.dmg path: output/PlayCover_${{ env.TAG_NAME }}.dmg diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 1115daa64..274b15031 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -10,7 +10,7 @@ jobs: runs-on: macos-12 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.0 - name: Install dependencies shell: bash @@ -57,7 +57,7 @@ jobs: run: rm apikey.json - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.3.0 with: name: PlayCover_nightly_${{ github.run_number }}.dmg path: output/PlayCover_nightly_${{ github.run_number }}.dmg diff --git a/.github/workflows/SwiftLint.yml b/.github/workflows/SwiftLint.yml index 1c0e198f0..3528c9789 100644 --- a/.github/workflows/SwiftLint.yml +++ b/.github/workflows/SwiftLint.yml @@ -12,7 +12,7 @@ jobs: SwiftLint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.0 - name: SwiftLint uses: norio-nomura/action-swiftlint@3.2.1 From 0ee66376e896b2ed8973c052bb13873458b6407b Mon Sep 17 00:00:00 2001 From: Ryu-ga Date: Tue, 30 Jan 2024 14:16:30 +0900 Subject: [PATCH 57/79] Chnage phase to remove quarantine --- PlayCover/AppInstaller/Installer.swift | 1 + PlayCover/Utils/IPA.swift | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PlayCover/AppInstaller/Installer.swift b/PlayCover/AppInstaller/Installer.swift index 5278109cb..594df5554 100644 --- a/PlayCover/AppInstaller/Installer.swift +++ b/PlayCover/AppInstaller/Installer.swift @@ -107,6 +107,7 @@ class Installer { } ipa.releaseTempDir() + try ipa.removeQuarantine(finalURL) InstallVM.shared.next(.finish, 0.95, 1.0) returnCompletion(finalURL) } catch { diff --git a/PlayCover/Utils/IPA.swift b/PlayCover/Utils/IPA.swift index e50764bd1..bdc423502 100644 --- a/PlayCover/Utils/IPA.swift +++ b/PlayCover/Utils/IPA.swift @@ -30,7 +30,7 @@ public class IPA { tmpDir = nil } - func removeQuarantine(_ execUrl: URL) throws { + public func removeQuarantine(_ execUrl: URL) throws { try Shell.run("/usr/bin/xattr", "-r", "-d", "com.apple.quarantine", execUrl.relativePath) } @@ -38,7 +38,6 @@ public class IPA { if let workDir = tmpDir { if try Shell.run("/usr/bin/unzip", "-oq", url.path, "-d", workDir.path) == "" { - try removeQuarantine(workDir) return try Installer.fromIPA(detectingAppNameInFolder: workDir.appendingPathComponent("Payload")) } else { throw PlayCoverError.appCorrupted From d7ac5381abdf28aec8f4be6d9dcf6a6dee755527 Mon Sep 17 00:00:00 2001 From: lucus lee Date: Thu, 15 Feb 2024 00:21:12 +0900 Subject: [PATCH 58/79] fix codesign script for xcode 15 (#1385) --- PlayCover.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 1cd233697..da355a6d4 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -605,7 +605,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\nLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\"\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME}\n\necho Signing location $LOCATION\necho Signing identity $IDENTITY\n# Apple Development: XIN LI (33X85HBRP6)\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\"\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\"\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\"\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\"\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\n\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME};\n# Apple Development: XIN LI (33X85HBRP6)\necho Signing identity $IDENTITY;\n\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle;\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework;\n\n# sign sparkle\nif [ \"$XCODE_VERSION_MAJOR\" -ge \"1500\" ]; then\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nelse\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nfi\n\n\n"; }; AAE8809C287ACA4900FBB23C /* Carthage Bootstrap */ = { isa = PBXShellScriptBuildPhase; From 0f3b97ff695452cb831059aa2261a37e1a602327 Mon Sep 17 00:00:00 2001 From: OHaiiBuzzle <23693150+ohaiibuzzle@users.noreply.github.com> Date: Thu, 15 Feb 2024 03:55:25 +0700 Subject: [PATCH 59/79] fix: make observation of modifier keys centralized (#1384) --- PlayCover.xcodeproj/project.pbxproj | 4 ++ PlayCover/AppInstaller/Installer.swift | 7 +--- PlayCover/Utils/ModifierKeyObserver.swift | 41 +++++++++++++++++++ .../Views/Settings/KeyCoverSettings.swift | 12 +++--- 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 PlayCover/Utils/ModifierKeyObserver.swift diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index da355a6d4..702cf602a 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ AA818CB5287ABEC3000BEE9D /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = AA818CB4287ABEC3000BEE9D /* Yams */; }; AB00EB5229A7BF17006F3225 /* KeyCover.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB00EB5129A7BF17006F3225 /* KeyCover.swift */; }; AB6F21EB299B7FA20078ADEC /* URLHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB6F21EA299B7FA20078ADEC /* URLHandler.swift */; }; + ABBC85B92B7C5CBA00DCF223 /* ModifierKeyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBC85B82B7C5CBA00DCF223 /* ModifierKeyObserver.swift */; }; ABDAD80629893CF900DC164F /* KeyCoverSetupViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABDAD80529893CF900DC164F /* KeyCoverSetupViews.swift */; }; ABDAD80A29893EA300DC164F /* KeyCoverSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABDAD80929893EA300DC164F /* KeyCoverSettings.swift */; }; ABDAD80C298A1E3E00DC164F /* KeyCoverViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABDAD80B298A1E3E00DC164F /* KeyCoverViews.swift */; }; @@ -177,6 +178,7 @@ AA970FD228793A310099A5D0 /* PlayCoverRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PlayCoverRelease.entitlements; sourceTree = ""; }; AB00EB5129A7BF17006F3225 /* KeyCover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyCover.swift; sourceTree = ""; }; AB6F21EA299B7FA20078ADEC /* URLHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLHandler.swift; sourceTree = ""; }; + ABBC85B82B7C5CBA00DCF223 /* ModifierKeyObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModifierKeyObserver.swift; sourceTree = ""; }; ABDAD80529893CF900DC164F /* KeyCoverSetupViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCoverSetupViews.swift; sourceTree = ""; }; ABDAD80929893EA300DC164F /* KeyCoverSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCoverSettings.swift; sourceTree = ""; }; ABDAD80B298A1E3E00DC164F /* KeyCoverViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCoverViews.swift; sourceTree = ""; }; @@ -329,6 +331,7 @@ B17FD03F28C70C7300B1D4CA /* CoreUI.h */, AB00EB5129A7BF17006F3225 /* KeyCover.swift */, AB6F21EA299B7FA20078ADEC /* URLHandler.swift */, + ABBC85B82B7C5CBA00DCF223 /* ModifierKeyObserver.swift */, ); path = Utils; sourceTree = ""; @@ -670,6 +673,7 @@ 6ECB1D0E29798DFA00CD92AA /* DataExtensions.swift in Sources */, 6E66B0D928A135360099B907 /* ToastVM.swift in Sources */, 92EE06D0274EA433002C907B /* BaseApp.swift in Sources */, + ABBC85B92B7C5CBA00DCF223 /* ModifierKeyObserver.swift in Sources */, 92F8500A27675124005CE6BE /* AppIntegrity.swift in Sources */, 6E06193828B3C4240012C771 /* ChangeGenshinAccountView.swift in Sources */, 68E48B97295704A600C39879 /* Downloader.swift in Sources */, diff --git a/PlayCover/AppInstaller/Installer.swift b/PlayCover/AppInstaller/Installer.swift index 594df5554..97dd0474b 100644 --- a/PlayCover/AppInstaller/Installer.swift +++ b/PlayCover/AppInstaller/Installer.swift @@ -42,7 +42,8 @@ class Installer { let installPlayTools: Bool let applicationType = InstallPreferences.shared.defaultAppType - if (Installer.isOptionKeyHeld || InstallPreferences.shared.showInstallPopup) && !export { + if (ModifierKeyObserver.shared.isOptionKeyPressed + || InstallPreferences.shared.showInstallPopup) && !export { installPlayTools = installPlayToolsPopup() } else { installPlayTools = InstallPreferences.shared.alwaysInstallPlayTools @@ -218,8 +219,4 @@ class Installer { try FileManager.default.moveItem(at: baseApp.url, to: location) return location } - - static var isOptionKeyHeld: Bool { - NSEvent.modifierFlags.contains(.option) - } } diff --git a/PlayCover/Utils/ModifierKeyObserver.swift b/PlayCover/Utils/ModifierKeyObserver.swift new file mode 100644 index 000000000..f9b6e33d2 --- /dev/null +++ b/PlayCover/Utils/ModifierKeyObserver.swift @@ -0,0 +1,41 @@ +// +// ModifierKeyObserver.swift +// PlayCover +// +// Created by Venti on 14/02/2024. +// + +import Foundation + +class ModifierKeyObserver: ObservableObject { + static let shared = ModifierKeyObserver() + + @Published var isOptionKeyPressed = false + @Published var isCommandKeyPressed = false + @Published var isControlKeyPressed = false + @Published var isShiftKeyPressed = false + + private var eventMonitor: Any? + + init() { + let mask: NSEvent.EventTypeMask = [.flagsChanged] + eventMonitor = NSEvent.addLocalMonitorForEvents(matching: mask) { [weak self] event in + guard let self = self else { return event } + if event.type == .flagsChanged { +// debugPrint("Event received: \(event)") + self.isOptionKeyPressed = event.modifierFlags.contains(.option) + self.isCommandKeyPressed = event.modifierFlags.contains(.command) + self.isControlKeyPressed = event.modifierFlags.contains(.control) + self.isShiftKeyPressed = event.modifierFlags.contains(.shift) + self.objectWillChange.send() + } + return event + } + } + + deinit { + if let eventMonitor = eventMonitor { + NSEvent.removeMonitor(eventMonitor) + } + } +} diff --git a/PlayCover/Views/Settings/KeyCoverSettings.swift b/PlayCover/Views/Settings/KeyCoverSettings.swift index 5c81f0383..0fb03c2ea 100644 --- a/PlayCover/Views/Settings/KeyCoverSettings.swift +++ b/PlayCover/Views/Settings/KeyCoverSettings.swift @@ -30,6 +30,8 @@ struct KeyCoverSettings: View { @ObservedObject var keyCoverPreferences = KeyCoverPreferences.shared @ObservedObject var keyCoverObserved = KeyCoverObservable.shared + @ObservedObject var modifierKeyObserver = ModifierKeyObserver.shared + var body: some View { VStack { HStack { @@ -45,7 +47,7 @@ struct KeyCoverSettings: View { Spacer() Button(keyCoverObserved.keyCoverEnabled ? "button.Reset" : "button.Enable") { if keyCoverObserved.keyCoverEnabled { - if isOptionKeyHeld() { + if modifierKeyObserver.isOptionKeyPressed { KeyCoverPassword.shared.forceResetKeyCoverPassword() } else { keyCoverRemovalViewShown = true @@ -54,7 +56,9 @@ struct KeyCoverSettings: View { keyCoverInitialSetupShown = true } } - .foregroundColor(keyCoverObserved.keyCoverEnabled ? .red : .none) + .foregroundColor((keyCoverObserved.keyCoverEnabled + && modifierKeyObserver.isOptionKeyPressed) + ? .red : .none) } .padding() Spacer() @@ -99,10 +103,6 @@ struct KeyCoverSettings: View { KeyCoverRemovalView(isPresented: $keyCoverRemovalViewShown) } } - - func isOptionKeyHeld() -> Bool { - NSEvent.modifierFlags.contains(.option) - } } struct KeyCoverSettings_Previews: PreviewProvider { From 866fd24a123785f34442b198af0433d492f6c17a Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:51:53 -0700 Subject: [PATCH 60/79] update macos runners + add back notarisation (#1386) --- .github/workflows/1.build_release.yml | 13 +++++-------- .github/workflows/2.nightly_release.yml | 2 +- .github/workflows/SwiftLint.yml | 3 +-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 3a180536f..c9c8ac480 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -10,7 +10,7 @@ env: CI: true jobs: build: - runs-on: macos-12 + runs-on: macos-14 steps: - name: Checkout uses: actions/checkout@v4.1.0 @@ -48,13 +48,10 @@ jobs: create-dmg ./output/PlayCover.app ./output mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg - # Will bring back when codesign id is updated - # - name: Notarize DMG - # shell: bash - # run: | - # fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg - # env: - # TAG_NAME: ${{ steps.tag_version.outputs.TAG_NAME }} + - name: Notarize DMG + shell: bash + run: | + fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg - name: Clean Up shell: bash diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 274b15031..40bcb96d6 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -7,7 +7,7 @@ env: CI: true jobs: build: - runs-on: macos-12 + runs-on: macos-14 steps: - name: Checkout uses: actions/checkout@v4.1.0 diff --git a/.github/workflows/SwiftLint.yml b/.github/workflows/SwiftLint.yml index 3528c9789..5a8895497 100644 --- a/.github/workflows/SwiftLint.yml +++ b/.github/workflows/SwiftLint.yml @@ -4,7 +4,7 @@ on: # Run on PR and push to every branch pull_request: push: - + # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -13,7 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.1.0 - - name: SwiftLint uses: norio-nomura/action-swiftlint@3.2.1 with: From 9aaa014724ce215bb1411188d46753e29ac50ca7 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:15:58 -0700 Subject: [PATCH 61/79] add python and node setup to actions --- .github/workflows/1.build_release.yml | 10 ++++++++++ .github/workflows/2.nightly_release.yml | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index c9c8ac480..8a662cf1c 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -15,6 +15,16 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.0 + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 'latest' + - name: Get the version id: tag_version run: echo "TAG_NAME=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 40bcb96d6..21a2e0a43 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -12,6 +12,16 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.0 + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 'latest' + - name: Install dependencies shell: bash run: | From 259467cadcad70f0ff38960edda4825b8a87fd11 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:11:04 -0700 Subject: [PATCH 62/79] pass `GITHUB_TOKEN` as `GITHUB_ACCESS_TOKEN` env --- .github/workflows/1.build_release.yml | 3 +++ .github/workflows/2.nightly_release.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 8a662cf1c..5f30213e3 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -11,6 +11,8 @@ env: jobs: build: runs-on: macos-14 + env: + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout uses: actions/checkout@v4.1.0 @@ -59,6 +61,7 @@ jobs: mv ./output/*.dmg ./output/PlayCover_${{ env.TAG_NAME }}.dmg - name: Notarize DMG + continue-on-error: true shell: bash run: | fastlane notarize_dmg package:output/PlayCover_${{ env.TAG_NAME }}.dmg diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index 21a2e0a43..acf631def 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -8,6 +8,8 @@ env: jobs: build: runs-on: macos-14 + env: + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout uses: actions/checkout@v4.1.0 From eb178d129999f6e796011b892a73ae3b448d17b1 Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 21 Feb 2024 14:56:20 +0900 Subject: [PATCH 63/79] fix ci target macos-14 --- .github/workflows/2.nightly_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/2.nightly_release.yml b/.github/workflows/2.nightly_release.yml index acf631def..14ea581e9 100644 --- a/.github/workflows/2.nightly_release.yml +++ b/.github/workflows/2.nightly_release.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick + brew install graphicsmagick imagemagick swiftlint gem install fastlane bundle install pip install setuptools From 701ec4d0c95e0b8cd78052e0a730ecf21ba01217 Mon Sep 17 00:00:00 2001 From: lucas lee Date: Wed, 21 Feb 2024 19:12:39 +0900 Subject: [PATCH 64/79] fix codesign script, again --- PlayCover.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 702cf602a..3ede6261c 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -608,7 +608,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\n\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME};\n# Apple Development: XIN LI (33X85HBRP6)\necho Signing identity $IDENTITY;\n\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle;\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework;\n\n# sign sparkle\nif [ \"$XCODE_VERSION_MAJOR\" -ge \"1500\" ]; then\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nelse\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nfi\n\n\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\n\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME};\n# Apple Development: XIN LI (33X85HBRP6)\necho Signing identity $IDENTITY;\n\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle;\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework;\n\n# sign sparkle\nif [ \"$XCODE_VERSION_MAJOR\" -ge \"1500\" ]; then\n\tLOCATION=\"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Autoupdate\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Updater.app\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Downloader.xpc\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Installer.xpc\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION\";\nelse\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nfi\n\n\n"; }; AAE8809C287ACA4900FBB23C /* Carthage Bootstrap */ = { isa = PBXShellScriptBuildPhase; From 2dc4249be76d9207185ecd04750fd244412dce12 Mon Sep 17 00:00:00 2001 From: lucus lee Date: Thu, 22 Feb 2024 02:21:09 +0900 Subject: [PATCH 65/79] fix ci pipelines again (#1397) --- .github/workflows/1.build_release.yml | 2 +- PlayCover.xcodeproj/project.pbxproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/1.build_release.yml b/.github/workflows/1.build_release.yml index 5f30213e3..accd28e7b 100644 --- a/.github/workflows/1.build_release.yml +++ b/.github/workflows/1.build_release.yml @@ -34,7 +34,7 @@ jobs: - name: Install dependencies shell: bash run: | - brew install graphicsmagick imagemagick + brew install graphicsmagick imagemagick swiftlint gem install fastlane bundle install pip install setuptools diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 3ede6261c..4f1719b04 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -608,7 +608,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\n\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME};\n# Apple Development: XIN LI (33X85HBRP6)\necho Signing identity $IDENTITY;\n\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle;\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework;\n\n# sign sparkle\nif [ \"$XCODE_VERSION_MAJOR\" -ge \"1500\" ]; then\n\tLOCATION=\"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Autoupdate\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Updater.app\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Downloader.xpc\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Installer.xpc\";\n\tcodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION\";\nelse\n\tLOCATION=\"${BUILD_DIR%Build/*}SourcePackages/artifacts/sparkle/Sparkle.xcframework/macos-arm64_x86_64/Sparkle.framework\";\n\techo Sparkle Signing location $LOCATION;\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Autoupdate\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Updater.app\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Downloader.xpc\";\n\tcodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/XPCServices/Installer.xpc\";\nfi\n\n\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nset -euo pipefail\n\nIDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME};\n# Apple Development: XIN LI (33X85HBRP6)\necho Signing identity $IDENTITY;\n\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework/PlugIns/AKInterface.bundle;\ncodesign --verbose --force --deep --sign \"$IDENTITY\" ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PlayTools.framework;\n\n# sign sparkle\nLOCATION=\"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework\";\necho Sparkle Signing location $LOCATION;\ncodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Autoupdate\";\ncodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/Updater.app\";\ncodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Downloader.xpc\";\ncodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION/Versions/B/XPCServices/Installer.xpc\";\ncodesign -f -o runtime -s \"$IDENTITY\" \"$LOCATION\";\n"; }; AAE8809C287ACA4900FBB23C /* Carthage Bootstrap */ = { isa = PBXShellScriptBuildPhase; From 08248df49a02667bbf5b3b52b39e1bce62e20d96 Mon Sep 17 00:00:00 2001 From: Sinon <34333654+Catta1997@users.noreply.github.com> Date: Thu, 2 May 2024 19:38:14 +0200 Subject: [PATCH 66/79] Added Italian Localizable.strings --- PlayCover/it.lproj/Localizable.strings | Bin 0 -> 37534 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 PlayCover/it.lproj/Localizable.strings diff --git a/PlayCover/it.lproj/Localizable.strings b/PlayCover/it.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..79f58251e46aef4fe27653ccd8de6e7027488fba GIT binary patch literal 37534 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 F{{_d%+B5(F literal 0 HcmV?d00001 From 92f206150c889ce02dd2fa2cab54dc577a443d9b Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 3 May 2024 16:33:31 -0600 Subject: [PATCH 67/79] fix subdirectory recursion --- PlayCover/Utils/Extensions/PlayAppExtensions.swift | 2 +- PlayCover/Views/Uninstaller.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PlayCover/Utils/Extensions/PlayAppExtensions.swift b/PlayCover/Utils/Extensions/PlayAppExtensions.swift index ef762bb14..0bfe36400 100644 --- a/PlayCover/Utils/Extensions/PlayAppExtensions.swift +++ b/PlayCover/Utils/Extensions/PlayAppExtensions.swift @@ -15,7 +15,7 @@ extension PlayApp { try? FileManager.default.createDirectory(at: appTmp, withIntermediateDirectories: false) - appTmp.enumerateContents(options: []) { url, type in + appTmp.enumerateContents { url, type in if url.lastPathComponent.contains("discord-ipc-") && (type.isSymbolicLink ?? true) { FileManager.default.delete(at: url) } diff --git a/PlayCover/Views/Uninstaller.swift b/PlayCover/Views/Uninstaller.swift index 474b49de4..1ab6b81b7 100644 --- a/PlayCover/Views/Uninstaller.swift +++ b/PlayCover/Views/Uninstaller.swift @@ -161,7 +161,7 @@ class Uninstaller { static func clearExternalCache(_ bundleId: String) { do { for cache in cacheURLs { - cache.enumerateContents(options: []) { file, _ in + cache.enumerateContents(options: [.skipsSubdirectoryDescendants]) { file, _ in if file.path.contains(bundleId) { try FileManager.default.trashItem(at: file, resultingItemURL: nil) } @@ -181,7 +181,7 @@ class Uninstaller { var prunedIds: [String] = [] for url in fullPruneURLs { - url.enumerateContents(options: []) { file, _ in + url.enumerateContents(options: [.skipsSubdirectoryDescendants]) { file, _ in let bundleId = file.deletingPathExtension().lastPathComponent if danglingItems.contains(bundleId) { try FileManager.default.trashItem(at: file, resultingItemURL: nil) From 38006198bfb38b97f310ebc992c57ffe9c148e64 Mon Sep 17 00:00:00 2001 From: "Stv.X" <30586070+Stv-X@users.noreply.github.com> Date: Wed, 29 May 2024 09:52:48 +0800 Subject: [PATCH 68/79] Adopt asynchronous methods to avoid UI blocking (#1274) * Modify PlayTools injection/removal methods to execute asynchronously to prevent UI blocking * Added async support for the two functionalities of "Insert Introspection libraries" and "Force Insert iOS Frameworks". * Add async support for "Clear App Data" button. * Add async support for app uninstaller. * Polish the UI and simplify the code. * Fixed an issue that may cause BypassesView to load unnecessary tasks. * Simplify code with a modern Swift concurrency version of method `beginSheetModal` in NSAlert. * Refactor Shell.signApp method to async. --- PlayCover/AppInstaller/Installer.swift | 2 +- PlayCover/Model/PlayApp.swift | 8 +- PlayCover/Utils/PlayTools.swift | 5 +- PlayCover/Views/App Views/PlayAppView.swift | 20 +--- PlayCover/Views/AppSettingsView.swift | 102 +++++++++++++++++--- PlayCover/Views/Uninstaller.swift | 54 +++++++---- 6 files changed, 139 insertions(+), 52 deletions(-) diff --git a/PlayCover/AppInstaller/Installer.swift b/PlayCover/AppInstaller/Installer.swift index 97dd0474b..4ed7981d2 100644 --- a/PlayCover/AppInstaller/Installer.swift +++ b/PlayCover/AppInstaller/Installer.swift @@ -80,7 +80,7 @@ class Installer { if export { try PlayTools.injectInIPA(app.executable, payload: app.url) } else if installPlayTools { - try PlayTools.installInIPA(app.executable) + try await PlayTools.installInIPA(app.executable) } app.info.applicationCategoryType = applicationType diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index d5373d2be..9197dbd82 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -36,10 +36,10 @@ class PlayApp: BaseApp { do { isStarting = true if prohibitedToPlay { - clearAllCache() + await clearAllCache() throw PlayCoverError.appProhibited } else if maliciousProhibited { - clearAllCache() + await clearAllCache() deleteApp() throw PlayCoverError.appMaliciousProhibited } @@ -216,7 +216,7 @@ class PlayApp: BaseApp { static let introspection: String = "/usr/lib/system/introspection" static let iosFrameworks: String = "/System/iOSSupport/System/Library/Frameworks" - func changeDyldLibraryPath(set: Bool? = nil, path: String) -> Bool { + func changeDyldLibraryPath(set: Bool? = nil, path: String) async -> Bool { info.lsEnvironment["DYLD_LIBRARY_PATH"] = info.lsEnvironment["DYLD_LIBRARY_PATH"] ?? "" if let set = set { @@ -257,7 +257,7 @@ class PlayApp: BaseApp { container.containerUrl.showInFinderAndSelectLastComponent() } - func clearAllCache() { + func clearAllCache() async { Uninstaller.clearExternalCache(info.bundleIdentifier) } diff --git a/PlayCover/Utils/PlayTools.swift b/PlayCover/Utils/PlayTools.swift index ea2c9f496..dd3745f9d 100644 --- a/PlayCover/Utils/PlayTools.swift +++ b/PlayCover/Utils/PlayTools.swift @@ -71,7 +71,7 @@ class PlayTools { } } - static func installInIPA(_ exec: URL) throws { + static func installInIPA(_ exec: URL) async throws { var binary = try Data(contentsOf: exec) try Macho.stripBinary(&binary) @@ -168,7 +168,7 @@ class PlayTools { }) } - static func removeFromApp(_ exec: URL) { + static func removeFromApp(_ exec: URL) async { Inject.removeMachO(machoPath: exec.path, cmdType: .loadDylib, backup: false, @@ -184,7 +184,6 @@ class PlayTools { if FileManager.default.fileExists(atPath: pluginUrl.path) { try FileManager.default.removeItem(at: pluginUrl) } - try Shell.signApp(exec) } catch { Log.shared.error(error) diff --git a/PlayCover/Views/App Views/PlayAppView.swift b/PlayCover/Views/App Views/PlayAppView.swift index 2f23bb73f..18f17ac60 100644 --- a/PlayCover/Views/App Views/PlayAppView.swift +++ b/PlayCover/Views/App Views/PlayAppView.swift @@ -7,6 +7,7 @@ import SwiftUI import DataCache struct PlayAppView: View { + @Binding var selectedBackgroundColor: Color @Binding var selectedTextColor: Color @Binding var selected: PlayApp? @@ -15,8 +16,6 @@ struct PlayAppView: View { @State var isList: Bool @State private var showSettings = false - @State private var showClearCacheAlert = false - @State private var showClearCacheToast = false @State private var showClearPreferencesAlert = false @State private var showClearPlayChainAlert = false @@ -104,7 +103,8 @@ struct PlayAppView: View { Divider() Group { Button(action: { - showClearCacheAlert.toggle() + selected = nil + Task { await Uninstaller.clearCachePopup(app) } }, label: { Text("playapp.clearCache") }) @@ -122,7 +122,7 @@ struct PlayAppView: View { Divider() Button(action: { selected = nil - Uninstaller.uninstallPopup(app) + Task { await Uninstaller.uninstallPopup(app) } }, label: { Text("playapp.delete") }) @@ -136,13 +136,6 @@ struct PlayAppView: View { .sheet(isPresented: $showDeleteGenshinAccount) { DeleteGenshinAccountView() } - .alert("alert.app.delete", isPresented: $showClearCacheAlert) { - Button("button.Proceed", role: .destructive) { - app.clearAllCache() - showClearCacheToast.toggle() - } - Button("button.Cancel", role: .cancel) { } - } .alert("alert.app.preferences", isPresented: $showClearPreferencesAlert) { Button("button.Proceed", role: .destructive) { deletePreferences(app: app.info.bundleIdentifier) @@ -157,11 +150,6 @@ struct PlayAppView: View { } Button("button.Cancel", role: .cancel) { } } - .onChange(of: showClearCacheToast) { _ in - ToastVM.shared.showToast( - toastType: .notice, - toastDetails: NSLocalizedString("alert.appCacheCleared", comment: "")) - } .onChange(of: showImportSuccess) { _ in ToastVM.shared.showToast( toastType: .notice, diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index 80d822d05..454333208 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -8,6 +8,10 @@ import SwiftUI import DataCache +enum BlockingTask { + case none, playTools, introspection, iosFrameworks, applicationCategoryType +} + // swiftlint:disable file_length struct AppSettingsView: View { @Environment(\.dismiss) var dismiss @@ -21,6 +25,7 @@ struct AppSettingsView: View { @State var hasPlayTools: Bool? @State var hasAlias: Bool? + @State private var currentTask = BlockingTask.none @State private var cache = DataCache.instance var body: some View { @@ -82,8 +87,7 @@ struct AppSettingsView: View { .disabled(!(hasPlayTools ?? true)) BypassesView(settings: $viewModel.settings, hasPlayTools: $hasPlayTools, - hasIntrospection: viewModel.app.changeDyldLibraryPath(path: PlayApp.introspection), - hasIosFrameworks: viewModel.app.changeDyldLibraryPath(path: PlayApp.iosFrameworks), + task: $currentTask, app: viewModel.app) .tabItem { Text("settings.tab.bypasses") @@ -93,6 +97,7 @@ struct AppSettingsView: View { closeView: $closeView, hasPlayTools: $hasPlayTools, hasAlias: $hasAlias, + task: $currentTask, app: viewModel.app, applicationCategoryType: viewModel.app.info.applicationCategoryType) .tabItem { @@ -123,6 +128,7 @@ struct AppSettingsView: View { .keyboardShortcut(.defaultAction) } } + .disabled(currentTask != .none) .onChange(of: resetSettingsCompletedAlert) { _ in ToastVM.shared.showToast( toastType: .notice, @@ -449,12 +455,27 @@ struct GraphicsView: View { struct BypassesView: View { @Binding var settings: AppSettings @Binding var hasPlayTools: Bool? + @Binding var task: BlockingTask - @State var hasIntrospection: Bool - @State var hasIosFrameworks: Bool + @State private var hasIntrospection: Bool + @State private var hasIosFrameworks: Bool var app: PlayApp + init(settings: Binding, + hasPlayTools: Binding, + task: Binding, + app: PlayApp) { + self._settings = settings + self._hasPlayTools = hasPlayTools + self._task = task + self.app = app + + let lsEnvironment = app.info.lsEnvironment["DYLD_LIBRARY_PATH"] ?? "" + self.hasIntrospection = lsEnvironment.contains(PlayApp.introspection) + self.hasIosFrameworks = lsEnvironment.contains(PlayApp.iosFrameworks) + } + var body: some View { ScrollView { VStack { @@ -477,22 +498,32 @@ struct BypassesView: View { HStack { Toggle("settings.toggle.introspection", isOn: $hasIntrospection) .help("settings.toggle.introspection.help") + .toggleStyle(.async($task, role: .introspection)) Spacer() } Spacer() HStack { Toggle("settings.toggle.iosFrameworks", isOn: $hasIosFrameworks) .help("settings.toggle.iosFrameworks.help") + .toggleStyle(.async($task, role: .iosFrameworks)) Spacer() } } .padding() } .onChange(of: hasIntrospection) {_ in - _ = app.changeDyldLibraryPath(set: hasIntrospection, path: PlayApp.introspection) + task = .introspection + Task { + _ = await app.changeDyldLibraryPath(set: hasIntrospection, path: PlayApp.introspection) + task = .none + } } .onChange(of: hasIosFrameworks) {_ in - _ = app.changeDyldLibraryPath(set: hasIosFrameworks, path: PlayApp.iosFrameworks) + task = .iosFrameworks + Task { + _ = await app.changeDyldLibraryPath(set: hasIosFrameworks, path: PlayApp.iosFrameworks) + task = .none + } } } } @@ -502,6 +533,7 @@ struct MiscView: View { @Binding var closeView: Bool @Binding var hasPlayTools: Bool? @Binding var hasAlias: Bool? + @Binding var task: BlockingTask @State var showPopover = false @@ -515,6 +547,11 @@ struct MiscView: View { HStack { Text("settings.applicationCategoryType") Spacer() + if task == .applicationCategoryType { + ProgressView() + .scaleEffect(0.5) + .frame(width: 16, height: 16) + } Picker("", selection: $applicationCategoryType) { ForEach(LSApplicationCategoryType.allCases, id: \.rawValue) { value in Text(value.localizedName) @@ -523,10 +560,12 @@ struct MiscView: View { } .frame(width: 225) .onChange(of: applicationCategoryType) { _ in + task = .applicationCategoryType app.info.applicationCategoryType = applicationCategoryType - Task(priority: .userInitiated) { + Task.detached { do { try Shell.signApp(app.executable) + task = .none } catch { Log.shared.error(error) } @@ -599,14 +638,14 @@ struct MiscView: View { Spacer() .frame(height: 20) HStack { - Button((hasPlayTools ?? true) ? "settings.removePlayTools" : "alert.install.injectPlayTools") { - closeView.toggle() + Button { + task = .playTools Task(priority: .userInitiated) { if hasPlayTools ?? true { - PlayTools.removeFromApp(app.executable) + await PlayTools.removeFromApp(app.executable) } else { do { - try PlayTools.installInIPA(app.executable) + try await PlayTools.installInIPA(app.executable) } catch { Log.shared.error(error) } @@ -616,7 +655,18 @@ struct MiscView: View { AppsVM.shared.filteredApps = [] AppsVM.shared.fetchApps() } + + task = .none + closeView.toggle() } + } label: { + Text((hasPlayTools ?? true) ? "settings.removePlayTools" : "alert.install.injectPlayTools") + .opacity(task == .playTools ? 0 : 1) + .overlay { + if task == .playTools { + ProgressView().scaleEffect(0.5) + } + } } Spacer() } @@ -705,3 +755,33 @@ struct InfoView: View { .padding() } } + +struct AsyncToggleStyle: ToggleStyle { + @Binding var task: BlockingTask + + var role: BlockingTask + + func makeBody(configuration: Configuration) -> some View { + if task == role { + return AnyView( + HStack(spacing: 3) { + ProgressView() + .scaleEffect(0.5) + .frame(width: 16, height: 16) + + configuration.label + } + ) + } else { + return AnyView( + Toggle(isOn: configuration.$isOn) { configuration.label } + ) + } + } +} + +extension ToggleStyle where Self == AsyncToggleStyle { + static func async(_ task: Binding, role: BlockingTask) -> AsyncToggleStyle { + AsyncToggleStyle(task: task, role: role) + } +} diff --git a/PlayCover/Views/Uninstaller.swift b/PlayCover/Views/Uninstaller.swift index 1ab6b81b7..d981a092f 100644 --- a/PlayCover/Views/Uninstaller.swift +++ b/PlayCover/Views/Uninstaller.swift @@ -45,7 +45,8 @@ class Uninstaller { return CheckBoxHelper(view: view, button: button, buttonvar: varname) } - static func uninstallPopup(_ app: PlayApp) { + @MainActor + static func uninstallPopup(_ app: PlayApp) async { if UninstallPreferences.shared.showUninstallPopup { let boxmakers: [(String, String)] = [ ("removePlayChain", NSLocalizedString("preferences.toggle.removePlayChain", comment: "")), @@ -89,30 +90,29 @@ class Uninstaller { delete.hasDestructiveAction = true - let response = alert.runModal() - - if response == .alertFirstButtonReturn { - for checkboxhelper in checkboxes { - UninstallPreferences.shared.setValue(checkboxhelper.button.state == .on, - forKey: checkboxhelper.buttonvar) - } - - if alert.suppressionButton?.state == .on { - UninstallPreferences.shared.showUninstallPopup = false - } + NSApplication.shared.requestUserAttention(.criticalRequest) + guard let window = NSApplication.shared.windows.first, + await alert.beginSheetModal(for: window) == .alertFirstButtonReturn else { return } + for checkboxhelper in checkboxes { + UninstallPreferences.shared.setValue(checkboxhelper.button.state == .on, + forKey: checkboxhelper.buttonvar) + } - uninstall(app) + if alert.suppressionButton?.state == .on { + UninstallPreferences.shared.showUninstallPopup = false } + + await uninstall(app) } else { - uninstall(app) + await uninstall(app) } } - static func uninstall(_ app: PlayApp) { + static func uninstall(_ app: PlayApp) async { var uninstallNum = 0 if UninstallPreferences.shared.clearAppData { - app.clearAllCache() + await app.clearAllCache() uninstallNum += 1 } @@ -150,7 +150,6 @@ class Uninstaller { do { let apps = (try PlayApp.bundleIDCache).filter({ $0 != app.info.bundleIdentifier }) .joined(separator: "\n") + "\n" - try apps.write(to: PlayApp.bundleIDCacheURL, atomically: false, encoding: .utf8) } catch { Log.shared.error(error) @@ -158,6 +157,27 @@ class Uninstaller { } } + @MainActor + static func clearCachePopup(_ app: PlayApp) async { + let alert = NSAlert() + alert.messageText = NSLocalizedString("alert.app.delete", comment: "") + alert.alertStyle = .warning + + let proceed = alert.addButton(withTitle: NSLocalizedString("button.Proceed", comment: "")) + proceed.hasDestructiveAction = true + alert.addButton(withTitle: NSLocalizedString("button.Cancel", comment: "")) + + NSApplication.shared.requestUserAttention(.criticalRequest) + guard let window = NSApplication.shared.windows.first, + await alert.beginSheetModal(for: window) == .alertFirstButtonReturn else { return } + + await clearCache(of: app) + } + + static func clearCache(of app: PlayApp) async { + await app.clearAllCache() + } + static func clearExternalCache(_ bundleId: String) { do { for cache in cacheURLs { From 7fb6709aea9623caf3fd2cfe990f0d3c7622dea1 Mon Sep 17 00:00:00 2001 From: Sinon <34333654+Catta1997@users.noreply.github.com> Date: Sun, 2 Jun 2024 22:54:01 +0200 Subject: [PATCH 69/79] Fix localization (#1498) * fix xcodeproj * Update Localizable.strings --- PlayCover.xcodeproj/project.pbxproj | 3 +++ PlayCover/it.lproj/Localizable.strings | Bin 37534 -> 18809 bytes 2 files changed, 3 insertions(+) diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 4f1719b04..de52000da 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -189,6 +189,7 @@ B17FD03828C70BAE00B1D4CA /* CoreUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreUI.framework; path = /System/Library/PrivateFrameworks/CoreUI.framework; sourceTree = ""; }; B17FD03F28C70C7300B1D4CA /* CoreUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreUI.h; sourceTree = ""; }; B17FD04628C7B0D900B1D4CA /* AssetsExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsExtractor.swift; sourceTree = ""; }; + B490E8692C0D0E8A004383FA /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; B6603E1028E206A300DEFA3F /* UninstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UninstallSettings.swift; sourceTree = ""; }; B6603E1228E2257800DEFA3F /* Uninstaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Uninstaller.swift; sourceTree = ""; }; B6825C3428F3D23600E3015A /* InstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallSettings.swift; sourceTree = ""; }; @@ -516,6 +517,7 @@ ro, hi, da, + it, ); mainGroup = 8783CFEE26B8C52D00171041; packageReferences = ( @@ -731,6 +733,7 @@ 6E692F1D290B349F0090D9EC /* ro */, 68C79E67296741580041DBC9 /* hi */, 6EA4A34B29B61CE9005F4679 /* da */, + B490E8692C0D0E8A004383FA /* it */, ); name = Localizable.strings; sourceTree = ""; diff --git a/PlayCover/it.lproj/Localizable.strings b/PlayCover/it.lproj/Localizable.strings index 79f58251e46aef4fe27653ccd8de6e7027488fba..527ec3daaea34e85bdd9d38f50ed11fa91e3abb7 100644 GIT binary patch literal 18809 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 Yq$9O~Qht{P{15*k=vEB9n#^ba2V%VLH~;_u literal 37534 zcmd6wU2hymc82@fzhW$4u?}KPvVao=8wA-ADOp@ovO-ce0^~*#DVnxKa!FdU{A+WW z0J+LtZjzj*ULKvQ>Z+ceA+rbsikj}~I;YOZdp@dq^gsXoV7MIK4ljp~_H$`}miGJD z{yZ2K!#~*1gJCtC+Ml!G=ixm4Ufhm+F#P@SncZ(ce>hy&6Ia9Q;iQ<0xfjE=-MzBe zPHfJbG@?D%wcWe1KWB;dbvD!9@Xjb-*i1LZ&#yM(!p5B0h~7*;*oY6qo{f5(<~z2z zud*4R-p+Pq^DS)DiOFSAjcw0;VVtm%9eeWi@Pqw3m)@mOIkTBoHtN!T@7gGM?s59s z=$_d9tLA)bv+Wio z=6ltox3U=*rgix@_J)-+$GQC$A}jjfBUt1#S4+FUV{_s&uak|QB?_->Mj|Kkq75Rh zK5Jc2<~orJufiK6%5zQ6!NG-P1zJ7v{w(3_zWsh>qli-lYEaVd&cwy4P0)sZsxve8-kXTQ0Re2qDL0*b=NcOVNo8j{rGMK{|c=RWe z&6#n3Vw8fvefzvf9)`W+8NzGVed!5{bYD?}c~}b`jvsBlx@oDuPu#eSmPUts0uF=w ze=^F*7pq)YMB=VL!Mgsvobjw>4j+_a8}kCJ;)B`4TlX6h_TVuVxYOlFOMJ$ip;3RdLu<3k_wVvr*F=pM`Vpfoe zCx|?uzqxUSxR0jsWREj+SY#7q1B=uffI?n(w^yEX<$5A>&U1mtSHOszK5HO5=+Reh z0&mFZ%zA>q-eR$GN+>d>-8cNw?t$HP7m4_RRi6!vsBH`my&npqf&GyW^-)DJN%5D; zY}_d=^Kbc>dTE^Z3u<;SFezO&~IM}sW$nCb_;#IOWcwEN^y-9wQTQBW5D>y51 z$$k5LZrRpi_|EQfZ}WNK=s4NV+q5E&b1#Mi>szWC3)&Y$RAW8cuQ?ZmAI-<8ltOBM zw9de{!?OmBg^i4k$&u+3IpBHQ&}Vg*Np|G6W%o2BxLb|dT#{5(%6{vtsLpp;o#eaD z3gGq^<2icCFfJ_q?)xm!8QbL03j z$vfzj8Juhgy?J$3@)!F-c(_OCBb%3sg7`X(p=H*GXMHf+_-IeooT@jU&+Hyjj-+zF zHf<4mh>d-&=&+HQf~NS!RjMtBN?2ob+(I__b?+oI-d9=A)~fo(vk`6cK8I!#cgTlT zlzn9?d*Zb^KDu{cpNK7`Zoe1u^0DnTJf44<@Vi7rc|RQq>cnw>Y&|C>Qcg+LZ6(&Z zGCxs2ZF&c3YS!APV)m9FkvPi6Tgg{j zW37`jb?0^5DaJ-~4IP>$$Pv_$RcFnSnXEQH*E61-*~lSJ(+oG3;n49=mKsw2E_uOO z$}*wm{X2AC&wwpRUeOoGJ9_IlqD%e8{@{1&@CHZh=jCTWz*X_8JIV!Rlf=f)jhFB2 znG5^3?<&d5u~AuzuK}CHZsE_flCq<5cg}Z>TRbNuyE3Zke&b*NVt44z^P4EE{aU1; z&T=`Tr)4w}t0B)hPbrn|=} zo1hfh*o=buK1XIlst!WVW!DGm0v8;?rFZuPuBzrxX3UN=f9BdAJGqyJDnXrEm)*u# zp=@D#USc$LBUVIjSEr|tAKm|Qw-y<4hkT~TXKOw>B*d+JH}0|V2_|ehn^2ORvz~D$ ztz36Nl;Dzh05v4d9--vIc;OspJaj6sj`dl_y#4%MKM*jgGGhTIHF%!?Z&7tA+6qk&vQx*y+dmOsXI0hhS}R zE-UvAuy_i*X|LbyGtUCTo{thXOQw=Pt88mRT#FlNq@@K;j?e*N|C0^?Cj(g(cF)@Q z#BPE1SgB!&{>smo&vOAE>HFAJTP_9oqi2Lgjco=FrsHPhzPY8iq}1Vv7%oo7GLt^| zyM99F$0YGUK-YUNK|Cz>C(!X-xsN?QM|m=k`kZWE@8hRheBZC;*?ULco_|m2Uh<@Z zkWFDZLOFUY;QzJ~gsLzG&kB9ZZ>8f?qk+X?fmo{V#d}93zfplYdV|YL)+uY zCPO~?{Q32WF1Zi*j=(BOlK88CVWsFCY@ioL4CCMR>9|9C&d;>F7O`bRkbKZ~FIU}K!^E-b9zSjm)c@B%@+)~Ibbb=SF&reGT zL6IK&mc$@(SUSq|ej^r8&+@Fx+tJZaMCt^%TQqB1cS>U{naGv4)q`79Ziitb+e)|P zQ>?VzOGTF6mEAKL(lfhByGqz~o-yr@I<-j6aY^w85A_)AIf>%e&vpl0W9vChWDjO| zZKv~-Hb(de$u4|;9LdRdVrC&OSF~GpGPLn8f5vHn zI`sE@r<&PiDzi)^3&Q90YQ5*YGd|Brka=rAKIg6#siZfs6_bqdrn4;C!#TbQz ze*bAaV3o2PA+lry5^@$XmycKaWH0c9pP$(pTlQPd%9H2Ak0udL{yH~DHoxz_<@Ggh z!3e?odtzl}v>CNHPg3tfMUKmi!G~lr=3COsElP+%&gAjkEjsTVnM1yFT6Gfiyb4?W_u^AtTGc3p*9}!Lo1utwgd6}d@WMxL4BL`*< zMld6vJVzI0(ZPd+!1%vx>*r6MCOyS@0R6#j&T;}1lNURKUsWn1^TK4QHpN!CvkqlXGsU|&Ko{w5m>$>5jqp3G>AmJB606YaD~oKJV!r* zx3T;5h#?W>T-g<}W)NYDDmIbp2u^gZ|J)0sh&}NRMo>IVJSeI=MR|%NJ-IC?8+GH#yU#&4_pVTj_2;kwY?bWblzAlY#j>-ck%b$zB!YImDFAh6{v=6RyK;2Awy;$I}v^OB1ggov70<=^xRInywZoTDze;I zHM2wGbE7M-Z1K8l^xAJe-GxW+znph2U&;a>8Si8=)N!(akX`6L@)*4}#}m|c$c>-R zO{%?KXMHMNIv|4P_T+CAB6-b@-k6;?a2LbZ$tvOvSv(6(vI~Pw@Q#Sk%BQhdWwhi1 z%5$)gww@%9oisA{h*BQPq=`$&1luRRk;%ZRY7o)llWae)o4BgAvZ|iU$e+oMy%vGi zlpHwI)lICjV`l<~sjGkkk`yHO? zJ}C*}MP!Du6`nYs)E%|}b`Y;QF>`IT26F7JuWjFCS2ZWdU#Lobr(I)oP8NeLAQvo+ zC*k6?{boHnX{k(%mH#}@iNFKKc%)c?rNV*oTjqrVzTyb)ayv;CAbNl^X$5;E)_6q2 zgU}d%kLxZh@C*A+7SNVC+Bm2E>Az@V8@zp;R>N*IbJQoaJdSuYfJ2XOtWN8Nz9Jz~ z%lqh(qSl|E{Q?n?qSO7{o_k{JL<9AnkUX=!`{UMy&aggg?Z)QtYSwp#qRPp!{Y|1s z1UXK9jKjn`$oMcx1OLs>0C-PP)pdWx;?>Vj;+LSI_H#K?bzoNZx5HPT_(bbSA9|{s zctedE6kf0g$2?^>@;N%1JVAyN-v)DJqYv#l#X#kE`5MTG15ai5LbCjcw`tu(L!Fz} z3gGe7o^RKLAsy`2BP|-0b#p?|(UIl1c+1cJ|6k3yG#?!2|Nc!9NFHxe_EW}1JQ3_v?HVh>*1-<>mG3d& z>FC`%r}!89gFmE5{lf0>43YGm{R?bj{=c-JZ|p~1Ddr@~d9PYrxm}`h?ezWDexrS8 zV5xomUmN$bTE>CXpzn#N>e?Iru-ly8K2_e465!Ndm>#Q9*!3-5-EQ6!f(6j&9rb2^mRj|{(0et|qg z2djjb$XBbE<@1C~9?oQi`pz0z(_9^_=cT2YZMlkg1=sU*Gza}ScZR<4_}3=?kl)wo z4!I_F(w7P+-l(}j60n)+K9&CS1+wDv?h)nSmY+vXbSSa6{EA6%;7=xG=G=TTqQqOba1306MbkBQx6j>CPL9CaJxV{ABV_8x3h!g@HZJJ&u!hD z)gZ%G?clpFQ#K7k&~vAM0xEz}?=1TS1y9Xa^4`qK*1&kp+t*xs&hKr;V|)IGjOTsh zl#V#De*UcJ6B_JGqVEIy+bt0tlwFgykBqT9&bP1EhI&!ZKd=>uW_Ul>h$~S$AE)ya zdW!7#Vgn!jU@KDI@geP1|B}fs)~3EKF^Nosnv}?)lQW7zpcHnP+lJ?lJm+45z1Du) z*L8_kV_s`4(KnGI9aXnbqgK%wAm@h&964Og4NqV(s<=QFKViwrmEjS6u`Nca0)Zy? z*a;s?B2GEM3sL8-{p}gU_UnIYb71pS+9g_1MLMOad}y77O9~}6$zS!Idx{~`SdeER zSPcj!ODd7;Fj?1$Ni?ipBN$Ik#V#>mFu!OenShJ02lkxE_1_q9JVY_ z)tRz!_C&A}G+uL}&pH3XSnSi+AscJ=kmwNLz0~ob3K;7)KBaSd5#HlCvVYenF2?tw zx8gLxa`z$R=A5)R?Ms|&34ET$*!_fWSR4M;%M3uo+*|QustT-3QY6nMZW1HZeO`yf zXpdE*m#{@LX0ED}skyP19&e&HT|K`t%cNSS-+?xR+QaNlpYPIke>6WSpY!fgoj2#B z!ejnuoZx5rF1wfM`ysxt+)@=O`{BYa$!03knC7eHJx8DBcK^s_2pKxybcQO z*ZOkbj3>zlx6w?ChgMglL|n;z+!JZ><^78mCU|@fy!z6lO01?+>5^uvp)gMU-Vd=bA0rQlO72cf0}g7Sx}uP4h%Rl z&d7mWdX9MNJI(QOG8uZfc!lHDk$tZ7!vmv~f3II_Y=1uk{9%t_S>@%=Zf!DF^vp(K z^X-}npPs6!gAQm-BmsA(sN~}|pP7@Eid%Z;u*@0jyJV28K-uHnD1T>kxbizE!PF$xxNZsYyKcDd)+OZUS93EbCoDqmuurb;YxIqt|_PoZziuB&D7T zr}^h`=2<|?7sj@)N~o@n=25D@mrLKmHSbxXAg7!1$gui!&F5%WAy^?1^KWLk}hK;7Hoq@d!Hgn#c~~JQH<#ta9Jh z-(MARUYP~|f)6lRbzdzT-O+xa-j2ZAi42UaJIVQ38)-r^)*f)I1({9rk5;Corqeji zKjYzR%zvC0#%joD;E8^j&`Z70rAdLDXwODyPO`C5s)|J|&j=dZQ0Sj#M@F7E!w=pe zdnH?QuVoa`?rMl#{|6>La6I<>=`x+B9(Mnm3KsSq3XJj$s-ANMXYI!sr{1~j6_7nLs^L{=MK@O8TSmM6tH8?eh*LvO{w9KzHK8m~ zWBeq9=6`Hs)uYXEOebrO2e2Ed$Hm> zT}LW)KYt|j_i7(J1&vt0{7ID!GX$NlhQG6MeE!P*d^!Bi{`HgXL;Y%g4;qx6L-qNE z3xRju!;dZ^l_nKGDNVu`BMbxL_%KSq*hx>B9j(+Xc`q?zRvu)AtU1(bUuyK~avqU&)?awcn@v5=U z=gAN8l2TIQmOOz-M|2cg5=FLK1v~M1AEv~frsgc_g zPXejGOP)m?9(paa*77^oywV)Us+DmfOahxY%Tz`$KZAwcknfUV&)N5;&eBdSo!y8# zocRoT`PnLBO&NX2En_Uase0Lz7c{Cp_;zOjy@YJ}6y4JKy@Q|v5~4diA+JS1N_D~X zMpj>Uy}4SwrRNEC)dvKB>DVhvm;A$)(Xh_p&7q99)ZaQ!l+{&Y;gt2o3SyoX_xr}N zzI_|pQtz&$5#M8te|l}JZm0H&bPi0|3aaY#K9L@)ddq?RP{k4VqbbTrh5yg7 zuFm$8G@{y@qJs@-$4d5;pD9p9g4D3?@)VZ%^1U^;L*J!B(_{}|Epm{ip`dt=Ct)-7 zjurawU9;$(x)wuQp-Jtv;pfVee5}56tzBuUwnbmsx#VdwKAoO-`l^|+5&9^2lqeuE zA|d@1ypWuUYo3edHW}QY1ICp$TJGvQ&v1q%s-|S0nkrgv!C;$670T?L_`F=HJ;L8^ zf~KBgJlep+sBAzh|IRh4M`rbt{Oj!A>+_{$*u2jc$g9t?I&4Vih44RB0WDs^9#9kH zLza1Uz#X!Q)_y#a=i4aY1`YnZja^v`e4KKBRei{1E)Tx?X`ipx{>0Wc#sG3f))W7y z0I~onWGj2dGk5))j`MdL4wF8)i^k`mLGa}34~_VhZFJ)PAdg3jaP4o0$V;eb^*v@f zZK*C(td(^OBd})8h=##BM+vYbq5{66Jp%3R$Z{NYRQ2*HzHJRFDbZy+skL?4(-nMz zw90><8b|K`QPp@PnYJlB9J%71OY>!Nv73aS<^SBHvp4Ged9^{F!TO(?l&M@5;U%qh z)GDbllJCUbvEQl(z?iTfuG8A_vD3FT_a19hD|G4D>g26dhye|BuuSQR!*PevY8?o;ig z6@?e^S$>8reUE4zZUhyN0U;T13)(~+)(ZU+S>2-<<=F*T!d#0{&Evao=y}iPjE=Fe z$FpkX67p4KAb((WA-@Od?W2#0KjoTq-?Z1tGi1eNS~@k9<57Kw3>u28mCO?_4C~?@ zr;-Y56&4Yx;9OQVMHAid44lEGvi6+6O}RiT$1|zVTQS&6OjU=~B|s)OmI3P^KjG~! z&RJlEKTXJ7K89?|HG4kk@6bnf4N|^0UX;_huTOKLU0*bEW4bKgu3^4DeRRr-z-+86 zYL9u8Wj&rz5RYn^hga2iBCB>Ty!R;DZ4F>^tdp~(OZ!b7E4%f+!r|=*{86V!u|oMu z^hU-KEoa7B>G#lWIi6V6>Qn9_zM#r_z=83KzqZ++qw2dal*u8 zqL1xgCqIpEkkB>%e%icx;*Mf&{$~D|$8z7m`CA#M`5UB7*iBpnr;e2MTj8FiF(;nFtp0r)m6KaXaoO9`+#{snQ9j6W=(Iw+5*aJ7-mx)t0?%!U`_wW~#M*BUd>6L1SPtrSj@+jZ3x10(q z<1B%`PfB%WO=~CFx@L6**-7@IuB6^Nr=ommXBi#+)=4+_t#+K-Gu{*z)QNMgv(ihW zRc0J*3)ZeqZ531*%z;kF2;SEZ@+E2#Gi%)0Zat-6qBlBvV9O?}l;so6$vN~b(RyAh zB+BdUBE2W6^_R4rDm=KBu?!-)5DNR3mi>N>K7GkSF-~=pVG32}Yrf=muKr!etiw-> zBNNuB8Mj+w+q(03ejoO*=_<=yK&x!)sLj7BB-N&^%u}@;c{F3_&&X2Qd5UZ|ucSf4 zk}GVfZznki$}&BZ3+&rZxF08jgt%0lJJY F{{_d%+B5(F From ff9a2d4d344ac523e6a8fdbcf944265b890081e9 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 3 Jun 2024 05:14:32 +0200 Subject: [PATCH 70/79] Translations update from Hosted Weblate (#1298) * Translated using Weblate (Turkish) Currently translated at 96.9% (258 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/tr/ Translation: PlayCover/PlayCover * Translated using Weblate (Portuguese (Brazil)) Currently translated at 88.3% (235 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/pt_BR/ Translation: PlayCover/PlayCover * Translated using Weblate (German) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (German) Currently translated at 100.0% (266 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Co-authored-by: SkyrilHD Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/de/ Translation: PlayCover/PlayCover * Translated using Weblate (Danish) Currently translated at 87.9% (234 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/da/ Translation: PlayCover/PlayCover * Translated using Weblate (Russian) Currently translated at 99.6% (265 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ru/ Translation: PlayCover/PlayCover * Translated using Weblate (Romanian) Currently translated at 60.1% (160 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ro/ Translation: PlayCover/PlayCover * Translated using Weblate (Ukrainian) Currently translated at 100.0% (0 of 0 strings) Added translation using Weblate (Ukrainian) Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Co-authored-by: Weblate Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/uk/ Translation: PlayCover/PlayCover * Translated using Weblate (Japanese) Currently translated at 88.7% (236 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ja/ Translation: PlayCover/PlayCover * Added translation using Weblate (Catalan) Co-authored-by: Hosted Weblate Co-authored-by: Weblate * Translated using Weblate (Vietnamese) Currently translated at 100.0% (266 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/vi/ Translation: PlayCover/PlayCover * Translated using Weblate (Hindi) Currently translated at 74.4% (198 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/hi/ Translation: PlayCover/PlayCover * Added translation using Weblate (Italian) Co-authored-by: Hosted Weblate Co-authored-by: Weblate * Added translation using Weblate (Arabic) Co-authored-by: Hosted Weblate Co-authored-by: Weblate * Translated using Weblate (Indonesian) Currently translated at 73.9% (199 of 269 strings) Translated using Weblate (Indonesian) Currently translated at 72.4% (195 of 269 strings) Translated using Weblate (Indonesian) Currently translated at 71.8% (191 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Ariq Pradipa Santoso Co-authored-by: Depa Panjie Purnama Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/id/ Translation: PlayCover/PlayCover * Translated using Weblate (Spanish) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (266 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Co-authored-by: gallegonovato Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/es/ Translation: PlayCover/PlayCover * Translated using Weblate (French) Currently translated at 83.4% (222 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fr/ Translation: PlayCover/PlayCover * Translated using Weblate (Persian) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (Persian) Currently translated at 75.5% (201 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Morteza Gharedaghi Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/fa/ Translation: PlayCover/PlayCover * Translated using Weblate (Korean) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (Korean) Currently translated at 99.6% (265 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Minseo Lee Co-authored-by: Prefill add-on Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ko/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (266 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Co-authored-by: Sherry Lo Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hant/ Translation: PlayCover/PlayCover * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (269 of 269 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (266 of 266 strings) Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Co-authored-by: Prefill add-on Co-authored-by: weng weng Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/ Translate-URL: https://hosted.weblate.org/projects/playcover/playcover/zh_Hans/ Translation: PlayCover/PlayCover * Italian https://github.com/PlayCover/PlayCover/pull/1498 --------- Co-authored-by: Prefill add-on Co-authored-by: SkyrilHD Co-authored-by: Ariq Pradipa Santoso Co-authored-by: Depa Panjie Purnama Co-authored-by: gallegonovato Co-authored-by: Morteza Gharedaghi Co-authored-by: Minseo Lee Co-authored-by: Sherry Lo Co-authored-by: weng weng Co-authored-by: Depal1 <47154119+Depal1@users.noreply.github.com> --- PlayCover/ar.lproj/Localizable.strings | 0 PlayCover/ca.lproj/Localizable.strings | 0 PlayCover/da.lproj/Localizable.strings | 7 +- PlayCover/de.lproj/Localizable.strings | 7 +- PlayCover/es.lproj/Localizable.strings | 7 +- PlayCover/fa.lproj/Localizable.strings | 117 ++++----- PlayCover/fr.lproj/Localizable.strings | 7 +- PlayCover/hi.lproj/Localizable.strings | 7 +- PlayCover/id.lproj/Localizable.strings | 25 +- PlayCover/ja.lproj/Localizable.strings | 7 +- PlayCover/ko.lproj/Localizable.strings | 11 +- PlayCover/pt-br.lproj/Localizable.strings | 7 +- PlayCover/ro.lproj/Localizable.strings | 7 +- PlayCover/ru.lproj/Localizable.strings | 7 +- PlayCover/tr.lproj/Localizable.strings | 7 +- PlayCover/uk.lproj/Localizable.strings | 269 ++++++++++++++++++++ PlayCover/vi.lproj/Localizable.strings | 7 +- PlayCover/zh-Hans.lproj/Localizable.strings | 7 +- PlayCover/zh-Hant.lproj/Localizable.strings | 7 +- 19 files changed, 415 insertions(+), 98 deletions(-) create mode 100644 PlayCover/ar.lproj/Localizable.strings create mode 100644 PlayCover/ca.lproj/Localizable.strings create mode 100644 PlayCover/uk.lproj/Localizable.strings diff --git a/PlayCover/ar.lproj/Localizable.strings b/PlayCover/ar.lproj/Localizable.strings new file mode 100644 index 000000000..e69de29bb diff --git a/PlayCover/ca.lproj/Localizable.strings b/PlayCover/ca.lproj/Localizable.strings new file mode 100644 index 000000000..e69de29bb diff --git a/PlayCover/da.lproj/Localizable.strings b/PlayCover/da.lproj/Localizable.strings index a38972441..a18100746 100644 --- a/PlayCover/da.lproj/Localizable.strings +++ b/PlayCover/da.lproj/Localizable.strings @@ -165,8 +165,6 @@ "settings.playChain.help" = "Aktiver PlayChain-understøttelse for denne app, så den (delvist) kan bruge Apple Keychain Services"; "settings.playChain.debugging" = "PlayChain debugging"; "settings.removePlayTools" = "Fjern PlayTools"; -"settings.addToLaunchpad" = "Føj til Launchpad"; -"settings.removeFromLaunchpad" = "Fjern fra Launchpad"; "settings.info.displayName" = "Vist navn:"; "settings.info.bundleName" = "Pakkenavn:"; "settings.info.bundleIdentifier" = "Pakke-id:"; @@ -264,3 +262,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/de.lproj/Localizable.strings b/PlayCover/de.lproj/Localizable.strings index 401b79843..b37464f53 100644 --- a/PlayCover/de.lproj/Localizable.strings +++ b/PlayCover/de.lproj/Localizable.strings @@ -367,8 +367,6 @@ "playapp.noSources.title" = "Keine IPAs installiert"; "playapp.noSources.subtitle" = "Du hast derzeit keine IPAs installiert. Klicke auf die Schaltfläche unten, um eine zu importieren."; "settings.tab.bypasses" = "Umgehungen"; -"settings.addToLaunchpad" = "Zum Launchpad hinzufügen"; -"settings.removeFromLaunchpad" = "Vom Launchpad entfernen"; "playapp.download.integrityCheck" = "Überprüfung der Dateiintegrität:"; "playapp.download.differentChecksum" = "Unterschiedliche Prüfsummen! Möchtest du mit der Installation fortfahren?"; "playapp.download.differentChecksumDesc" = "\"%@\" erwartet, \"%@\" erhalten"; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Tastenbelegung automatisch deaktivieren, wenn eine Texteingabe erkannt wird"; "settings.applicationCategoryType" = "Anwendungsart"; +"settings.toggle.iosFrameworks" = "Das Einfügen von iOS-Frameworks erzwingen"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Scrollrad in Keymapping aktivieren"; +"settings.toggle.iosFrameworks.help" = "Füge der App die System-ios-Bibliotheken hinzu. Es ist bekannt, dass Probleme behoben werden, bei denen einige Apps das ios-Framework nicht finden können"; +"settings.toggle.enableScrollWheel" = "Scrollrad aktivieren"; diff --git a/PlayCover/es.lproj/Localizable.strings b/PlayCover/es.lproj/Localizable.strings index 3013f5fef..a46a32929 100644 --- a/PlayCover/es.lproj/Localizable.strings +++ b/PlayCover/es.lproj/Localizable.strings @@ -367,8 +367,6 @@ "playapp.noSources.title" = "No hay IPA instalados"; "playapp.noSources.subtitle" = "Actualmente no tiene ninguna IPA instalada. Haga clic en el botón de abajo para importar uno."; "settings.tab.bypasses" = "Bypass"; -"settings.addToLaunchpad" = "Agregar al Launchpad"; -"settings.removeFromLaunchpad" = "Quitar del Launchpad"; "playapp.download.integrityCheck" = "Verificar la integridad de los archivos:"; "playapp.download.differentChecksum" = "Las sumas de control difieren. ¿Quiere proceder con la instalación?"; "playapp.download.differentChecksumDesc" = "Se esperaba «%@»; se obtuvo «%@»"; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "Mapa de teclas inteligente"; "settings.toggle.autoKM.help" = "Desactivación automática de la asignación de las teclas cuando se detecta la entrada del texto"; "settings.applicationCategoryType" = "Tipo de la aplicación"; +"settings.toggle.iosFrameworks" = "Forzar la inserción de marcos iOS"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Activar la rueda de desplazamiento en la asignación de teclas"; +"settings.toggle.iosFrameworks.help" = "Agregue las bibliotecas del sistema ios a la aplicación. Se sabe que soluciona problemas en los que algunas aplicaciones no pueden encontrar el marco de iOS"; +"settings.toggle.enableScrollWheel" = "Activar rueda de desplazamiento"; diff --git a/PlayCover/fa.lproj/Localizable.strings b/PlayCover/fa.lproj/Localizable.strings index 3faabc4b3..ba9d63fd8 100644 --- a/PlayCover/fa.lproj/Localizable.strings +++ b/PlayCover/fa.lproj/Localizable.strings @@ -215,60 +215,63 @@ "settings.playChain.enable" = "فعال‌سازی PlayChain (آزمایشی)"; "settings.playChain.help" = "فعال‌سازی PlayChain برای این برنامه تا حدودی دسترسی آن را به سرویس‌های Keychain اپل فراهم می‌کند"; "settings.playChain.debugging" = "اشکال‌زدای PlayChain"; -"playapp.noSources.title" = "No IPAs Installed"; -"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; -"settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; -"playapp.progress.canceled" = "Canceled"; -"playapp.download.integrityCheck" = "Verifying file integrity:"; -"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; -"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; -"playapp.clearPlayChain" = "Clear PlayChain Data"; -"playapp.importIPA" = "Import IPA"; -"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; -"preferences.toggle.removePlayChain" = "Remove PlayChain"; -"preferences.popover.duplicate" = "Duplicate Link"; -"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; -"button.Reload" = "Reload"; -"settings.highResolution" = "High resolution may cause crashing"; -"settings.picker.windowFix" = "Fix window display issues"; -"settings.picker.windowFix.help" = "Apply window fixes that may helps your apps display normally"; -"settings.picker.windowFixMethod.0" = "Normal"; -"settings.picker.windowFixMethod.1" = "Alternate"; -"preferences.popover.checking" = "Checking URL"; -"settings.toggle.introspection" = "Insert Introspection libraries"; -"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; -"settings.picker.scaler" = "Resolution Scaler"; -"button.Enable" = "Enable"; -"settings.toggle.rootWorkDir" = "Start app at root directory"; -"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; -"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; -"keycover.masterPassword" = "Master Password"; -"keycover.confirmMasterPassword" = "Confirm Master Password"; -"keycover.oldMasterPassword" = "Current Master Password"; -"keycover.error.blankPassword" = "Password cannot be blank"; -"keycover.error.notMatch" = "Passwords do not match"; -"keycover.error.incorrectPassword" = "Incorrect Password"; -"keycover.status.title" = "KeyCover Status:"; -"keycover.status.managedPassword" = "Enabled with Managed Password"; -"keycover.status.userPassword" = "Enabled with User Password"; -"keycover.status.chainCount" = "KeyCover Chain Status: "; -"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; -"keycover.button.lockAll" = "Lock All Chains"; -"keycover.button.changePassword" = "Change Master Password"; -"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; -"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; -"keycover.setup.useGeneratedKey" = "Managed Automatically"; -"keycover.setup.useUserKey" = "Use my own key"; -"keycover.setup.encryptionKey" = "Encryption Key: "; -"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; -"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; -"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; -"keycover.alert.title" = "Keychain was not unlocked"; -"keycover.alert.content" = "Keychain access has been disabled for the current session"; -"settings.toggle.autoKM" = "Smart Keymap"; -"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; -"settings.applicationCategoryType" = "Application Type"; +"playapp.noSources.title" = "برنامه ای نصب نشده"; +"playapp.noSources.subtitle" = "شما در حال حاضر برنامه ای نصب نکرده اید، برای نصب از طریق دکمه پایین اقدام کنید."; +"settings.tab.bypasses" = "دور زدن"; +"playapp.progress.canceled" = "لغو شده"; +"playapp.download.integrityCheck" = "بررسی یکپارچگی فایل:"; +"playapp.download.differentChecksum" = "چک های ناهمسان! آیا می خواهید به نصب ادامه دهید؟"; +"playapp.download.differentChecksumDesc" = "انتظار میرفت \"@%\" دریافت شود، ولی \"@%\" دریافت شد"; +"playapp.clearPlayChain" = "پاک کردن اطلاعات PlayChain"; +"playapp.importIPA" = "بارگذاری فایل IPA"; +"ipaLibrary.noNetworkConnection.required" = "کتابخانه IPA به اتصال به اینترنت نیاز دارد"; +"preferences.toggle.removePlayChain" = "حذف PlayChain"; +"preferences.popover.duplicate" = "تکرار پیوند"; +"alert.app.clearPlayChain" = "تمام داده های PlayChain پاک خواهد شد. ممکن است لازم باشد دوباره وارد برنامه شوید. آیا مایل هستید ادامه دهید؟"; +"button.Reload" = "بارگذاری مجدد"; +"settings.highResolution" = "وضوح بالا ممکن است باعث کرش شود"; +"settings.picker.windowFix" = "رفع مشکلات نمایش پنجره"; +"settings.picker.windowFix.help" = "اعمال اصلاحات پنجره که ممکن است به نمایش درست برنامه ها کمک کند"; +"settings.picker.windowFixMethod.0" = "طبیعی"; +"settings.picker.windowFixMethod.1" = "متناوب"; +"preferences.popover.checking" = "در حال بررسی لینک"; +"settings.toggle.introspection" = "افزودن کتابخانه های Introspection"; +"settings.toggle.introspection.help" = "افزودن کتابخانه های introspection سیستمی. برای زمانهایی که بعضی برنامه ها به درستی اجرا نمیشوند"; +"settings.picker.scaler" = "مقیاس کننده رزولوشن"; +"button.Enable" = "فعال"; +"settings.toggle.rootWorkDir" = "شروع برنامه از دایرکتوری ریشه"; +"keycover.changePasswordPrompt.title" = "برای به‌روزرسانی کلید رمزگذاری KeyCover، رمز اصلی قدیمی و جدید خود را وارد کنید"; +"button.Reset" = "بازنشانی"; +"button.Unlock" = "باز کردن قفل"; +"settings.toggle.rootWorkDir.help" = "تغییر دایرکتوری کاری برنامه مانند iOS به /. اگر برنامه درست کار نکرد این گزینه را خاموش کنید"; +"keycover.masterPassword" = "گذرواژه اصلی"; +"keycover.confirmMasterPassword" = "تایید گذرواژه اصلی"; +"keycover.oldMasterPassword" = "گذرواژه اصلی فعلی"; +"keycover.error.blankPassword" = "رمز عبور نمی تواند خالی باشد"; +"keycover.error.notMatch" = "رمزهای ورود مطابقت ندارند"; +"keycover.error.incorrectPassword" = "رمز عبور نادرست"; +"keycover.status.title" = "وضیعت KeyCover:"; +"keycover.status.managedPassword" = "فعال شده با رمز عبور مدیریت شده"; +"keycover.status.userPassword" = "فعال شدع با رمز عبور کاربر"; +"keycover.status.chainCount" = "وضیعت زنجیره KeyCover: "; +"keycover.status.unlockedCount %@ %@" = "زنجیرهای گشوده شده در @% جمعا @%"; +"keycover.button.lockAll" = "قفل تمام زنجیر"; +"keycover.button.changePassword" = "رمز عبور اصلی را تغییر دهید"; +"keycover.toggle.startupPrompt" = "پرسش برای KeyCover در زمان راه اندازی"; +"keycover.toggle.startupPrompt.help" = "در زمان راه اندازی اولیه برنامه، KeyCover گذرواژه اصلی را از شما میپرسد. اگر غیرفعال باشد، هنگامی که برنامه ای را راه اندازی می کنید که از PlayChain استفاده می کند، گذرواژه اصلی از شما خواسته می شود."; +"keycover.setup.useGeneratedKey" = "به صورت خودکار مدیریت می شود"; +"keycover.setup.useUserKey" = "از کلید خودم استفاده کن"; +"keycover.setup.encryptionKey" = "کلید رمزگذاری: "; +"keycover.setupPrompt.title" = "رمز عبور اصلی را برای استفاده برای KeyCover وارد کنید"; +"keycover.removePrompt.title" = "رمز عبور اصلی خود را برای حذف رمزگذاری KeyCover وارد کنید"; +"keycover.unlockPrompt.title" = "رمز عبور اصلی خود را برای باز کردن قفل KeyCover وارد کنید"; +"keycover.alert.title" = "Keychain باز نشده است"; +"keycover.alert.content" = "دسترسی به Keychain برای جلسه فعلی غیرفعال شده است"; +"settings.toggle.autoKM" = "نقشه کلید هوشمند"; +"settings.toggle.autoKM.help" = "غیرفعال سازی نقشه کلید به طور خودکار، زمانی که ورودی متن احساس میشود"; +"settings.applicationCategoryType" = "نوع برنامه"; +"settings.toggle.iosFrameworks" = "افزودن اجباری فریمورک های iOS"; +"settings.info.alias" = "نام مستعار:"; +"settings.toggle.enableScrollWheel.help" = "فعالسازی پیمایش در نقشه کلید"; +"settings.toggle.iosFrameworks.help" = "افزودن کتابخانه های سیستمی iOS به برنامه، برای رفع مشکل برخی از برنامه ها که نمیتوانند کتابخانه های iOS را پیدا کنند"; +"settings.toggle.enableScrollWheel" = "فعال سازی اسکرول"; diff --git a/PlayCover/fr.lproj/Localizable.strings b/PlayCover/fr.lproj/Localizable.strings index 72c7e560e..a10d08d2e 100644 --- a/PlayCover/fr.lproj/Localizable.strings +++ b/PlayCover/fr.lproj/Localizable.strings @@ -367,8 +367,6 @@ "playapp.noSources.title" = "Aucun IPA installé"; "playapp.noSources.subtitle" = "Actuellement, vous n'avez aucun IPA installé. Cliquez sur le bouton ci-dessous pour en importer un."; "settings.tab.bypasses" = "Contournements"; -"settings.addToLaunchpad" = "Ajouter à Launchpad"; -"settings.removeFromLaunchpad" = "Supprimer de Launchpad"; "playapp.download.integrityCheck" = "Vérification de l'intégrité des fichiers :"; "playapp.download.differentChecksum" = "Différentes sommes de contrôle ! Voulez-vous continuer l’installation ?"; "playapp.download.differentChecksumDesc" = "Attendu \"%@\", obtenu \"%@\""; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias :"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/hi.lproj/Localizable.strings b/PlayCover/hi.lproj/Localizable.strings index d656d3d72..b1b2ed672 100644 --- a/PlayCover/hi.lproj/Localizable.strings +++ b/PlayCover/hi.lproj/Localizable.strings @@ -210,8 +210,6 @@ "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; "settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; "playapp.progress.canceled" = "Canceled"; "playapp.download.integrityCheck" = "Verifying file integrity:"; "playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; @@ -264,3 +262,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/id.lproj/Localizable.strings b/PlayCover/id.lproj/Localizable.strings index 9ecc4b092..cad39c05f 100644 --- a/PlayCover/id.lproj/Localizable.strings +++ b/PlayCover/id.lproj/Localizable.strings @@ -323,13 +323,13 @@ "settings.removePlayTools" = "Hapus PlayTools"; "settings.info.playTools" = "PlayTools terpasang:"; "playapp.refreshSources" = "Menyegarkan sumber"; -"error.appMaliciousProhibited" = "This App behaves maliciously on Macs, and using it can leave your device in an unbootable state, therefore it is blocked from PlayCover. (Uninstalling...)"; +"error.appMaliciousProhibited" = "Aplikasi ini berperilaku dengan jahat di Mac, dan menggunakannya dapat membuat perangkat Anda tidak dapat dinyalakan, oleh karena itu diblokir dari PlayCover. (Menghapus Instalan...)"; "alert.install.injectPlayToolsQuestion" = "Apakah Anda ingin menyuntikkan PlayTools ke dalam aplikasi ini?"; "alert.install.playToolsInformative" = "PlayTools adalah alat yang memungkinkan Anda untuk mengikat tombol ke sentuhan layar, resolusi tampilan khusus, dan banyak lagi, tetapi dapat merusak aplikasi tertentu"; "button.Help" = "Bantuan"; "button.Dismiss" = "Abaikan"; -"state.enabled" = "Enabled"; -"state.disabled" = "Disabled"; +"state.enabled" = "Diaktifkan"; +"state.disabled" = "Nonaktif"; "configSigning.header" = "Configure Package Signing"; "configSigning.info.SIP" = "SIP is required to be fully to partially disabled in order for AMFI to be turned off."; "configSigning.subtext" = "Package Signing helps fixing issues with apps that rely on \ncorrect Team IDs for operations like authorization. \nThere may be security risks associated with enabling this feature.\n\n As such, we recommend disabling it when it's not necessary"; @@ -345,7 +345,7 @@ "configSigning.step.complete" = "Package Signing has been configured successfully"; "configSigning.alert.copied" = "Command Copied!"; "configSigning.alert.info" = "Please paste and run the command in Terminal.app. Your Mac will reboot after"; -"state.pendingReboot" = "Pending Reboot"; +"state.pendingReboot" = "Menunggu Menyalakan Ulang"; "menubar.configSigning" = "Configure Signing"; "alert.power.title" = "Mode Daya Rendah Diaktifkan!"; "alert.power.subtitle" = "Beberapa aplikasi tidak akan berfungsi dengan Mode Daya Rendah diaktifkan. Disarankan untuk menonaktifkannya."; @@ -363,12 +363,10 @@ "settings.playChain.enable" = "Enable PlayChain (experimental)"; "settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; "settings.playChain.debugging" = "PlayChain debugging"; -"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"error.failedToStripBinary" = "Tidak dapat menemukan arsitektur ARM64 dalam fat binary!"; "playapp.noSources.title" = "Tidak ada IPA yang Diinstal"; "playapp.noSources.subtitle" = "Saat ini Anda belum memiliki IPA yang terinstal. Klik tombol di bawah ini untuk mengimpornya."; "settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; "playapp.download.integrityCheck" = "Memverifikasi integritas file:"; "playapp.download.differentChecksum" = "Checksum yang berbeda! Apakah Anda ingin melanjutkan penginstalan?"; "playapp.download.differentChecksumDesc" = "Diharapkan \"%@\", yang didapat adalah \"%@\""; @@ -390,8 +388,8 @@ "settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; "settings.picker.scaler" = "Resolution Scaler"; "button.Enable" = "Aktifkan"; -"button.Reset" = "Reset"; -"button.Unlock" = "Unlock"; +"button.Reset" = "Atur ulang"; +"button.Unlock" = "Buka"; "settings.toggle.rootWorkDir" = "Start app at root directory"; "keycover.masterPassword" = "Master Password"; "keycover.alert.content" = "Keychain access has been disabled for the current session"; @@ -418,6 +416,11 @@ "keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; "keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; "keycover.alert.title" = "Keychain was not unlocked"; -"settings.toggle.autoKM" = "Smart Keymap"; -"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"settings.toggle.autoKM" = "Keymap Pintar"; +"settings.toggle.autoKM.help" = "Menonaktifkan pemetaan kunci secara otomatis ketika input teks terdeteksi."; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/ja.lproj/Localizable.strings b/PlayCover/ja.lproj/Localizable.strings index 6ddb15062..1af7b734f 100644 --- a/PlayCover/ja.lproj/Localizable.strings +++ b/PlayCover/ja.lproj/Localizable.strings @@ -366,9 +366,7 @@ "settings.playChain.debugging" = "PlayChain のデバッグ"; "playapp.noSources.title" = "IPA がインストールされていません"; "playapp.noSources.subtitle" = "現在、IPA はインストールされていません。 下のボタンをクリックしてインポートします。"; -"settings.addToLaunchpad" = "Launchpadに追加"; "settings.tab.bypasses" = "回避"; -"settings.removeFromLaunchpad" = "Launchpadから削除"; "playapp.download.integrityCheck" = "ファイルの整合性の検証中:"; "playapp.download.differentChecksum" = "チェックサムが異なります! インストールを続行しますか?"; "playapp.download.differentChecksumDesc" = "期待される \"%@\", got \"%@\""; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/ko.lproj/Localizable.strings b/PlayCover/ko.lproj/Localizable.strings index bb957da49..3060949af 100644 --- a/PlayCover/ko.lproj/Localizable.strings +++ b/PlayCover/ko.lproj/Localizable.strings @@ -313,7 +313,7 @@ "preferences.prune.alert" = "모든 파일을 정리하겠습니까?"; "preferences.prune.message" = "설정, 키매핑, 자격 증명, 앱 데이터를 포함한 모든 불필요한 것을 제거합니다"; "menubar.clearCache" = "캐시 지우기"; -"preferences.tab.install" = "설치하기"; +"preferences.tab.install" = "설치"; "preferences.toggle.showInstallPopup" = "PlayTools 설치 팝업 보기"; "preferences.toggle.alwaysInstallPlayTools" = "항상 PlayTools 설치"; "alert.install.injectPlayTools" = "PlayTools 주입"; @@ -367,8 +367,6 @@ "playapp.noSources.title" = "설치된 IPA 없음"; "playapp.noSources.subtitle" = "현재 설치된 IPA가 없습니다. 아래 버튼을 클릭하여 가져오세요."; "settings.tab.bypasses" = "우회"; -"settings.addToLaunchpad" = "Launchpad에 추가하기"; -"settings.removeFromLaunchpad" = "Launchpad에서 제거하기"; "playapp.download.integrityCheck" = "파일 무결성 확인:"; "playapp.download.differentChecksum" = "체크섬이 다릅니다! 설치를 계속하겠습니까?"; "playapp.download.differentChecksumDesc" = "\"%@\"이(가) 아닌 \"%@\"을(를) 받았습니다"; @@ -420,4 +418,9 @@ "keycover.alert.content" = "현재 세션의 Keychain 접근이 비활성화되었습니다"; "settings.toggle.autoKM" = "키매핑 시작"; "settings.toggle.autoKM.help" = "텍스트 입력이 감지되면 자동으로 키매핑 비활성화"; -"settings.applicationCategoryType" = "Application Type"; +"settings.applicationCategoryType" = "애플리케이션 유형"; +"settings.toggle.iosFrameworks" = "iOS 프레임워크 강제 삽입"; +"settings.info.alias" = "별명:"; +"settings.toggle.enableScrollWheel.help" = "키매핑에서 스크롤 휠 사용"; +"settings.toggle.iosFrameworks.help" = "앱에 시스템 iOS 라이브러리를 추가합니다. iOS 프레임워크를 찾을 수 없는 일부 앱의 문제를 해결합니다"; +"settings.toggle.enableScrollWheel" = "스크롤 휠 사용"; diff --git a/PlayCover/pt-br.lproj/Localizable.strings b/PlayCover/pt-br.lproj/Localizable.strings index 203cab2fd..065e0463a 100644 --- a/PlayCover/pt-br.lproj/Localizable.strings +++ b/PlayCover/pt-br.lproj/Localizable.strings @@ -210,8 +210,6 @@ "playapp.noSources.title" = "Nenhum IPA instalado"; "playapp.noSources.subtitle" = "Você atualmente não possui nenhum IPA instalado. Clique no botão abaixo para importar um."; "settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Adicionar ao Launchpad"; -"settings.removeFromLaunchpad" = "Remover do Launchpad"; "playapp.download.integrityCheck" = "Verificando integridade do arquivo:"; "playapp.download.differentChecksum" = "Checksums diferentes! Continuar a instalação?"; "playapp.download.differentChecksumDesc" = "Era esperado o valor \"%@\", porém foi recebido \"%@\""; @@ -264,3 +262,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/ro.lproj/Localizable.strings b/PlayCover/ro.lproj/Localizable.strings index 27be3b55e..a104e0c24 100644 --- a/PlayCover/ro.lproj/Localizable.strings +++ b/PlayCover/ro.lproj/Localizable.strings @@ -210,8 +210,6 @@ "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; "settings.tab.bypasses" = "Bypasses"; -"settings.addToLaunchpad" = "Add to Launchpad"; -"settings.removeFromLaunchpad" = "Remove from Launchpad"; "playapp.progress.canceled" = "Canceled"; "playapp.download.integrityCheck" = "Verifying file integrity:"; "playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; @@ -264,3 +262,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/ru.lproj/Localizable.strings b/PlayCover/ru.lproj/Localizable.strings index 8803e1ea7..95149cf26 100644 --- a/PlayCover/ru.lproj/Localizable.strings +++ b/PlayCover/ru.lproj/Localizable.strings @@ -366,9 +366,7 @@ "settings.playChain.debugging" = "Откладка PlayChain"; "playapp.noSources.title" = "IPA не установлены"; "playapp.noSources.subtitle" = "Сейчас у вас нет установленных IPA. Нажмите на кнопку ниже для импорта."; -"settings.removeFromLaunchpad" = "Удалить из Launchpad"; "settings.tab.bypasses" = "Обходы"; -"settings.addToLaunchpad" = "Добавить в Launchpad"; "playapp.download.integrityCheck" = "Проверка целостности файлов:"; "playapp.download.differentChecksum" = "Контрольные суммы не совпадают! Вы хотите продолжить установку?"; "playapp.download.differentChecksumDesc" = "Ожидалось \"%@\", получено \"%@\""; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "Умная раскладка"; "settings.toggle.autoKM.help" = "Автоматически выключать раскладку при вводе текста"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/tr.lproj/Localizable.strings b/PlayCover/tr.lproj/Localizable.strings index 7ee510ce6..a37aa81fa 100644 --- a/PlayCover/tr.lproj/Localizable.strings +++ b/PlayCover/tr.lproj/Localizable.strings @@ -210,8 +210,6 @@ "playapp.noSources.title" = "Yüklü IPA Yok"; "playapp.noSources.subtitle" = "İndirilmiş IPA yok. Eklemek için aşağıya tıklayınız."; "settings.tab.bypasses" = "Baypaslar"; -"settings.addToLaunchpad" = "Launchpad'a Ekle"; -"settings.removeFromLaunchpad" = "Launchpad'dan Kaldır"; "playapp.download.integrityCheck" = "Dosya bütünlüğü doğrulanıyor:"; "playapp.download.differentChecksum" = "Farklı sağlama toplamları var! İndirmeye devam etmeği istiyor musunuz?"; "playapp.download.differentChecksumDesc" = "Beklenen \"%@\", alınan \"%@\""; @@ -264,3 +262,8 @@ "settings.toggle.autoKM" = "Smart Keymap"; "settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; "settings.applicationCategoryType" = "Application Type"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/uk.lproj/Localizable.strings b/PlayCover/uk.lproj/Localizable.strings new file mode 100644 index 000000000..3ad0b8404 --- /dev/null +++ b/PlayCover/uk.lproj/Localizable.strings @@ -0,0 +1,269 @@ +"settings.tab.km" = "Keymapping"; +"ipaLibrary.noSources.subtitle" = "You currently have no IPA Sources added. Click the button below to add one."; +"alert.app.delete" = "All app data will be erased. You may need to download app files again. Do you wish to continue?"; +"alert.appCacheCleared" = "App data has been cleared!"; +"settings.text.image" = "Image"; +"ipaLibrary.noSources.button" = "Add Source"; +"keycover.masterPassword" = "Master Password"; +"button.Proceed" = "Proceed"; +"keycover.toggle.startupPrompt.help" = "KeyCover will prompt for your master password when you launch the application. If this is disabled, it will be prompted when you launch an app that uses PlayChain."; +"keycover.error.notMatch" = "Passwords do not match"; +"configSigning.step.disableAMFI" = "Please disable AMFI"; +"settings.picker.adaptiveRes.help" = "Changes the app's window resolution"; +"keycover.setup.useUserKey" = "Use my own key"; +"playapp.delete" = "Uninstall App"; +"settings.highResolution" = "High resolution may cause crashing"; +"storeAccount.nameOfAcc.textfieldPlaceholder" = "Name of account..."; +"settings.picker.windowFixMethod.0" = "Normal"; +"ipaLibrary.noNetworkConnection.required" = "IPA Library requires internet connection"; +"settings.info.executableName" = "Executable name:"; +"alert.legacyImport.title" = "Legacy App Settings Detected!"; +"preferences.prune.message" = "This will remove all unused files including settings, keymappings, entitlements, and app data"; +"playapp.deleteAccount" = "Delete Account"; +"menubar.website" = "Website"; +"sidebar.ipaLibrary" = "IPA Library"; +"alert.restart" = "Please restart PlayCover."; +"alert.install.injectPlayToolsQuestion" = "Do you want to inject PlayTools into this application?"; +"soundAlert.informativeText" = "Your current output device does not have a sample rate of 48 or 44.1 kHz! Crashes may occur. Would you like to change your current output device's sample rate to 48 kHz?"; +"alert.power.subtitle" = "Some apps will not work with Low Power Mode enabled. It is recommended to disable it."; +"playapp.download.downloading" = "Downloading"; +"error.noGenshinAccount" = "We couldn't find a Genshin account! Are you signed into an account in-app?"; +"error.appMaliciousProhibited" = "This App behaves maliciously on Macs, and using it can leave your device in an unbootable state, therefore it is blocked from PlayCover. (Uninstalling...)"; +"button.Reset" = "Reset"; +"ipaLibrary.version.newer" = "This version is newer than the version you have installed"; +"configSigning.action.copyCommand" = "Copy Command to Clipboard"; +"settings.toggle.jbBypass.help" = "Attempts to bypass Jailbreak Detection in some games (Not guaranteed to work all the time)"; +"menubar.exportToSideloady" = "Export to Sideloadly"; +"state.disabled" = "Disabled"; +"alert.moveAppToApplications.subtitle" = "PlayCover must be in the Applications folder to run correctly. Press the button below to move PlayCover automatically."; +"settings.toggle.autoKM.help" = "Automatically disable keymapping when text input is sensed"; +"menubar.clearCache" = "Clear Cache"; +"alert.storeAccount.regionIsNotValid" = "The current account is set to a different Region. Launch the game, Change the region, and pass through the gates to save. Then try again"; +"preferences.toggle.removePlayChain" = "Remove PlayChain"; +"configSigning.info.AMFI" = "AMFI is required to be turned off in order to allow fake signing of apps, allowing them to run with the correct Team ID"; +"button.Close" = "Close"; +"alert.errorImportKm" = "Error occured when importing!"; +"preferences.toggle.showInstallPopup" = "Show install PlayTools popup"; +"playapp.install.unzip" = "Extracting app from .ipa file..."; +"preferences.toggle.clearAppData" = "Clear data"; +"sidebar.appLibrary" = "App Library"; +"settings.toggle.lldbWithTerminal" = "Open in terminal"; +"configSigning.info.SIPHeader" = "System Integrity Protection"; +"settings.text.details.help" = "First row below title"; +"error.corruptedIPA" = "This .ipa file is corrupted. It does not contains \"Info.plist\" file."; +"ipaLibrary.version.same" = "App already installed"; +"playapp.addSource" = "Add source"; +"settings.text.details" = "Details"; +"keycover.setupPrompt.title" = "Enter a master password to use for KeyCover"; +"settings.removePlayTools" = "Remove PlayTools"; +"settings.info.url" = "URL:"; +"preferences.popover.duplicate" = "Duplicate Link"; +"configSigning.info.AMFIHeader" = "Apple Mobile File Integrity"; +"settings.resetSettingsCompleted" = "Settings have been reverted back to default!"; +"storeAccount.storeAcc" = "Store an account"; +"settings.playChain.debugging" = "PlayChain debugging"; +"playapp.clearPlayChain" = "Clear PlayChain Data"; +"alert.success" = "Success"; +"alert.install.injectPlayTools" = "Inject PlayTools"; +"preferences.button.moveSourceDown" = "Move Source Down"; +"settings.tab.graphics" = "Graphics"; +"state.pendingReboot" = "Pending Reboot"; +"alert.wrongFileType.subtitle" = "PlayCover can only install valid .ipa files."; +"configSigning.action.restart" = "Restart my Mac"; +"keycover.changePasswordPrompt.title" = "Enter your old master password and a new one to update your KeyCover encryption key"; +"settings.info.bundleIdentifier" = "Bundle identifier:"; +"settings.toggle.disableDisplaySleep" = "Disable display sleep"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"preferences.button.deleteSource" = "Delete Source"; +"playapp.add" = "Add app"; +"keycover.alert.title" = "Keychain was not unlocked"; +"settings.resetKm" = "Reset keymapping"; +"keycover.status.unlockedCount %@ %@" = "%@ unlocked chains in %@ total"; +"preferences.button.pruneFiles" = "Prune Files"; +"keycover.status.userPassword" = "Enabled with User Password"; +"keycover.unlockPrompt.title" = "Enter your master password to unlock KeyCover"; +"settings.text.customHeight" = "Height"; +"settings.text.image.help" = "Link to image or Dev portal asset name"; +"settings.info.bundleVersion" = "Bundle version:"; +"configSigning.header" = "Configure Package Signing"; +"alert.supression" = "You can change this in the PlayCover preferences"; +"preferences.toggle.removeEntitlements" = "Remove entitlements"; +"configSigning.info.SIP" = "SIP is required to be fully to partially disabled in order for AMFI to be turned off."; +"button.Dismiss" = "Dismiss"; +"soundAlert.messageText" = "Incorrect Audio Settings Detected!"; +"keycover.button.lockAll" = "Lock All Chains"; +"keycover.setup.useGeneratedKey" = "Managed Automatically"; +"configSigning.action.shutdown" = "Shut down my Mac"; +"settings.text.state.help" = "Second row below title"; +"settings.info.alias" = "Alias:"; +"settings.toggle.introspection.help" = "Add the system introspection libraries to the app. Known to fix issues with some apps not starting correctly"; +"playapp.download.differentChecksum" = "Different checksums! Do you want to continue to install?"; +"configSigning.alert.info" = "Please paste and run the command in Terminal.app. Your Mac will reboot after"; +"keycover.button.changePassword" = "Change Master Password"; +"settings.picker.scaler" = "Resolution Scaler"; +"playapp.openCache" = "Open App Data"; +"settings.slider.mouseSensitivity" = "Mouse sensitivity: %.f"; +"error.failedToStripBinary" = "Could not find ARM64 arch in fat binary!"; +"settings.picker.iosDevice" = "iOS device:"; +"settings.toggle.km.help" = "Add keyboard support to touch-only games. Use Command + K to open editor menu."; +"preferences.tab.uninstall" = "Uninstall"; +"button.Unlock" = "Unlock"; +"settings.resetSettings" = "Reset settings"; +"button.OK" = "OK"; +"preferences.popover.checking" = "Checking URL"; +"settings.info.playTools" = "PlayTools installed:"; +"button.No" = "No"; +"preferences.tab.ipasource" = "IPA Sources"; +"storeAccount.alert.restoreAccount" = "Really Restore Account?"; +"menubar.github" = "GitHub"; +"ipaLibrary.alert.download" = "Are you sure you want to download this version of %@?"; +"button.Help" = "Help"; +"preferences.popover.badjson" = "JSON Invalid or Not Found!"; +"alert.app.preferences" = "All in-app preferences will be deleted. Do you wish to continue?"; +"storeAccount.selectAccRegion.euro" = "Europe"; +"preferences.popover.valid" = "Link Valid"; +"playapp.install.signing" = "Signing app..."; +"settings.text.state" = "State"; +"menubar.discord" = "Discord"; +"storeAccount.selectAccRegion.cht" = "TW, HK, MO"; +"playapp.settings" = "Settings"; +"settings.tab.info" = "Info"; +"settings.text.debugger" = "Debugger:"; +"settings.info.displayName" = "Display name:"; +"settings.toggle.rootWorkDir.help" = "Change the working directory of the app to / just like on iOS. Turn this off if the app misbehave"; +"storeAccount.alert.restoreAccount.msg" = "This will override your currently signed-in account."; +"settings.info.minimumOSVersion" = "Minimum OS version:"; +"alert.legacyImport.subtitle" = "Legacy settings and keymapping files were detected. Would you like to convert these files to the new format?"; +"storeAccount.alert.deleteAccount" = "Really Delete Account?"; +"preferences.toggle.removeKeymap" = "Remove keymap"; +"playapp.exportKm" = "Export Keymapping"; +"storeAccount.deleteAcc" = "Delete an account"; +"storeAccount.selectAcc" = "Select an account"; +"keycover.confirmMasterPassword" = "Confirm Master Password"; +"keycover.status.title" = "KeyCover Status:"; +"alert.install.playToolsInformative" = "PlayTools is a tool that allows you to bind keys to screen touches, custom display resolutions, and more, but it may break certain apps"; +"playapp.progress.finished" = "Finished"; +"settings.text.applicationID" = "Application ID"; +"menubar.checkForUpdates" = "Check for Updates..."; +"playapp.storeCurrentAccount" = "Store Account"; +"ipaLibrary.download" = "Download"; +"keycover.error.blankPassword" = "Password cannot be blank"; +"storeAccount.nameOfAcc" = "Name of your account"; +"keycover.toggle.startupPrompt" = "Prompt for KeyCover at startup"; +"alert.power.title" = "Low Power Mode Enabled!"; +"keycover.alert.content" = "Keychain access has been disabled for the current session"; +"playapp.importKm" = "Import Keymapping"; +"storeAccount.alert.restoreAccount.button" = "Restore Account"; +"alert.wrongFileType.title" = "Wrong file type!"; +"keycover.oldMasterPassword" = "Current Master Password"; +"notification.appInstalled.message" = "Check it out in PlayCover!"; +"settings.tab.bypasses" = "Bypasses"; +"settings.resetKmCompleted" = "Keymapping has been reset!"; +"settings.picker.adaptiveRes.1" = "Auto (Based on Display)"; +"settings.picker.aspectRatio" = "Aspect ratio:"; +"settings.toggle.jbBypass" = "Enable Jailbreak Bypass (Experimental)"; +"button.Install" = "Install"; +"settings.button.clearActivity" = "Clear custom activity"; +"settings.playChain.help" = "Enable PlayChain support for this application, allowing it to (partially) use Apple Keychain Services"; +"configSigning.step.disableSIP" = "Please disable SIP from Recovery Mode"; +"menubar.configSigning" = "Configure Signing"; +"settings.toggle.lldb" = "Open with LLDB"; +"keycover.removePrompt.title" = "Enter your master password to remove KeyCover encryption"; +"preferences.button.checkForUpdates" = "Check for Updates"; +"button.Quit" = "Quit"; +"playapp.activateAccount" = "Switch Account"; +"playapp.showInFinder" = "Show in Finder"; +"preferences.button.addSource" = "Add Source"; +"settings.toggle.rootWorkDir" = "Start app at root directory"; +"preferences.toggle.removeSetting" = "Remove settings"; +"button.Reload" = "Reload"; +"error.appEncrypted" = "This app is encrypted! Please use a decrypted IPA. iMazing IPAs are not supported!"; +"playapp.clearCache" = "Clear App Data"; +"storeAccount.store" = "Store account"; +"preferences.button.moveSourceUp" = "Move Source Up"; +"preferences.whenUninstalling" = "When uninstalling:"; +"settings.text.customWidth" = "Width"; +"keycover.error.incorrectPassword" = "Incorrect Password"; +"playapp.noSources.title" = "No IPAs Installed"; +"settings.picker.windowFix.help" = "Apply window fixes that may helps your apps display normally"; +"menubar.documentation" = "Documentation"; +"storeAccount.selectAccRegion" = "Select account region"; +"alert.differentBundleIdKeymap.text" = "Are you sure you want to import this keymap?"; +"alert.differentBundleIdKeymap.message" = "The keymap may have been created for another application."; +"storeAccount.selectAccRegion.usa" = "America"; +"settings.picker.windowFix" = "Fix window display issues"; +"settings.toggle.hud" = "Metal HUD"; +"settings.noPlayTools" = "PlayTools is not installed in this app"; +"settings.button.discord" = "Custom Discord activity"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"preferences.prune.alert" = "Are you sure you want to prune all files?"; +"playapp.deleteMessage" = "Are you sure you want to uninstall %@?"; +"settings.text.detectedResolution" = "Detected Resolution:"; +"settings.info.bundleName" = "Bundle name:"; +"ipaLibrary.version.older" = "This version is older than the one you have installed"; +"error.appCorrupted" = "Something went wrong with this IPA. Please try to use another IPA file."; +"preferences.popover.badurl" = "URL Invalid!"; +"alert.app.clearPlayChain" = "All PlayChain data will be erased. You may need to login to the app again. Do you wish to continue?"; +"settings.playChain.enable" = "Enable PlayChain (Experimental)"; +"settings.toggle.autoKM" = "Smart Keymap"; +"error.waitInstallation" = "Please wait for the current installation to finish!"; +"settings.tab.misc" = "Misc"; +"playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"settings.toggle.disableDisplaySleep.help" = "Prevent display from turning off while this app is running"; +"settings.picker.adaptiveRes.0" = "App Default"; +"ipaLibrary.noNetworkConnection.toast" = "No internet connection!"; +"notification.appInstalled" = "App installed!"; +"preferences.toggle.alwaysInstallPlayTools" = "Always install PlayTools"; +"settings.toggle.discord" = "Enable Discord activity"; +"settings.unavailable.hud" = "Metal HUD unavailable"; +"button.Enable" = "Enable"; +"alert.kmImported" = "Keymapping imported!"; +"playapp.install.copy" = "Copying app..."; +"error.waitDownload" = "Please wait for the current download to finish!"; +"playapp.progress.failed" = "Failed"; +"preferences.toggle.automaticUpdates" = "Automatically check for updates"; +"soundAlert.failureText" = "Failed to set current output device's sample rate to 48 kHz. You can manually set sample rate in the Audio MIDI Setup app"; +"settings.toggle.introspection" = "Insert Introspection libraries"; +"alert.moveAppToApplications.move" = "Move to Applications folder"; +"alert.error" = "An error occurred!"; +"playapp.exportKmPanel.fieldLabel" = "PlayMap Name:"; +"playapp.download.integrityCheck" = "Verifying file integrity:"; +"settings.title" = "%@ Settings"; +"preferences.tab.install" = "Install"; +"settings.applicationCategoryType" = "Application Type"; +"storeAccount.alert.deleteAccount.button" = "Delete Account"; +"keycover.status.chainCount" = "KeyCover Chain Status: "; +"settings.toggle.km" = "Keymapping"; +"playapp.download.differentChecksumDesc" = "Expected \"%@\", got \"%@\""; +"error.appProhibited" = "Using this app through PlayCover will likely result in a ban!"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"playapp.install.addToLib" = "Adding app to library..."; +"settings.picker.adaptiveRes.5" = "Custom"; +"soundAlert.successText" = "Current output device sample rate set to 48 kHz"; +"button.Cancel" = "Cancel"; +"menubar.log.copy" = "Copy Logs"; +"playapp.progress.canceled" = "Canceled"; +"settings.picker.adaptiveRes" = "Resolution:"; +"configSigning.subtext" = "Package Signing helps fixing issues with apps that rely on \ncorrect Team IDs for operations like authorization. \nThere may be security risks associated with enabling this feature.\n\n As such, we recommend disabling it when it's not necessary"; +"button.Yes" = "Yes"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; +"alert.moveAppToApplications.title" = "Move to Applications folder?"; +"configSigning.step.AMFIreboot" = "AMFI Disabled. Please reboot"; +"preferences.textfield.url" = "Source URL..."; +"configSigning.step.complete" = "Package Signing has been configured successfully"; +"keycover.setup.encryptionKey" = "Encryption Key: "; +"keycover.status.managedPassword" = "Enabled with Managed Password"; +"state.enabled" = "Enabled"; +"playapp.deleteConfirm" = "Uninstall"; +"playapp.refreshSources" = "Refresh Sources"; +"ipaLibrary.noSources.title" = "No IPA Sources Added"; +"playapp.importIPA" = "Import IPA"; +"playapp.install.installPlayTools" = "Installing PlayTools..."; +"button.Convert" = "Convert"; +"settings.picker.windowFixMethod.1" = "Alternate"; +"playapp.install.createWrapper" = "Creating app wrapper..."; +"storeAccount.selectAccRegion.asia" = "Asia"; +"configSigning.alert.copied" = "Command Copied!"; +"playapp.clearPreferences" = "Clear App Preferences"; +"preferences.tab.updates" = "Updates"; +"preferences.toggle.showUninstall" = "Show warning popup"; diff --git a/PlayCover/vi.lproj/Localizable.strings b/PlayCover/vi.lproj/Localizable.strings index 4b0fcf79f..3f87e2d7a 100644 --- a/PlayCover/vi.lproj/Localizable.strings +++ b/PlayCover/vi.lproj/Localizable.strings @@ -218,8 +218,6 @@ "playapp.noSources.title" = "Chưa có ứng dụng nào"; "playapp.noSources.subtitle" = "Hiện tại bạn chưa có ứng dụng nào cả. Click bên dưới để nhập file IPA."; "settings.tab.bypasses" = "Bypass"; -"settings.addToLaunchpad" = "Thêm vào Launchpad"; -"settings.removeFromLaunchpad" = "Xóa khỏi Launchpad"; "playapp.download.integrityCheck" = "Xác minh tính toàn vẹn của tệp:"; "playapp.download.differentChecksum" = "Checksum khác nhau! Bạn có muốn tiếp tục cài đặt không?"; "playapp.download.differentChecksumDesc" = "Dự kiến \"%@\", đã xong \"%@\""; @@ -272,3 +270,8 @@ "settings.toggle.autoKM" = "Keymap thông minh"; "settings.toggle.autoKM.help" = "Tự động vô hiệu hóa keymapping khi phát hiện nhập văn bản"; "settings.applicationCategoryType" = "Loại ứng dụng"; +"settings.toggle.iosFrameworks" = "Force Insert iOS Frameworks"; +"settings.info.alias" = "Alias:"; +"settings.toggle.enableScrollWheel.help" = "Enable scroll wheel in keymapping"; +"settings.toggle.iosFrameworks.help" = "Add the system ios libraries to the app. Known to fix issues with some apps cannot find ios framework"; +"settings.toggle.enableScrollWheel" = "Enable Scroll Wheel"; diff --git a/PlayCover/zh-Hans.lproj/Localizable.strings b/PlayCover/zh-Hans.lproj/Localizable.strings index 285be6eb0..5efd96efd 100644 --- a/PlayCover/zh-Hans.lproj/Localizable.strings +++ b/PlayCover/zh-Hans.lproj/Localizable.strings @@ -367,8 +367,6 @@ "playapp.noSources.title" = "没有已安装的 IPA"; "playapp.noSources.subtitle" = "当前你没有安装任何 IPA。点击下面的按钮来导入一个。"; "settings.tab.bypasses" = "绕过"; -"settings.addToLaunchpad" = "添加到启动台"; -"settings.removeFromLaunchpad" = "从启动台移除"; "playapp.download.integrityCheck" = "正在验证文件完整性:"; "playapp.download.differentChecksum" = "校验不一致!你是否想要继续安装?"; "playapp.download.differentChecksumDesc" = "预期为 \"%@\", 当前为 \"%@\""; @@ -421,3 +419,8 @@ "settings.toggle.autoKM" = "智能按键映射"; "settings.toggle.autoKM.help" = "当检测到文本输入时自动禁用按键映射"; "settings.applicationCategoryType" = "应用程序类型"; +"settings.toggle.iosFrameworks" = "强制插入iOS框架"; +"settings.info.alias" = "别名:"; +"settings.toggle.enableScrollWheel.help" = "在按键映射启用滚轮"; +"settings.toggle.iosFrameworks.help" = "将系统 ios 库添加到应用程序中。已知可修复某些应用程序找不到 ios 框架的问题"; +"settings.toggle.enableScrollWheel" = "启用滚轮"; diff --git a/PlayCover/zh-Hant.lproj/Localizable.strings b/PlayCover/zh-Hant.lproj/Localizable.strings index 4ea8bd029..29d41db2a 100644 --- a/PlayCover/zh-Hant.lproj/Localizable.strings +++ b/PlayCover/zh-Hant.lproj/Localizable.strings @@ -347,8 +347,6 @@ "playapp.noSources.title" = "尚未安裝任何 IPA"; "playapp.noSources.subtitle" = "暫時沒有安裝任何 IPA 文件。點擊下方的按鈕來導入一個。"; "settings.tab.bypasses" = "繞道"; -"settings.removeFromLaunchpad" = "自啟動台移除"; -"settings.addToLaunchpad" = "加入啟動台"; "playapp.download.integrityCheck" = "驗證檔案的完整性:"; "playapp.download.differentChecksum" = "checksum 不相符!是否繼續安裝?"; "playapp.download.differentChecksumDesc" = "預期「%@」,得到「%@」"; @@ -401,3 +399,8 @@ "settings.toggle.autoKM" = "智能按鍵映射"; "settings.toggle.autoKM.help" = "當感應到文本輸入時,自動停用按鍵映射"; "settings.applicationCategoryType" = "應用程式類型"; +"settings.toggle.iosFrameworks" = "強制插入 iOS 框架"; +"settings.info.alias" = "別名:"; +"settings.toggle.enableScrollWheel.help" = "在鍵盤映射中啟用滾輪"; +"settings.toggle.iosFrameworks.help" = "將系統 ios 庫新增至應用程式。 已知修復某些應用程式找不到 ios 框架的問題"; +"settings.toggle.enableScrollWheel" = "啟用滾輪"; From 547c31febc66582b6aec570fb381a53381ae20eb Mon Sep 17 00:00:00 2001 From: Sinon <34333654+Catta1997@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:30:04 +0200 Subject: [PATCH 71/79] Added PUBG India to prohibited apps --- PlayCover/Model/PlayApp.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index 9197dbd82..528089b18 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -301,6 +301,7 @@ class PlayApp: BaseApp { "com.tencent.tmgp.cod", "com.tencent.ig", "com.pubg.newstate", + "com.pubg.imobile", "com.tencent.tmgp.pubgmhd", "com.dts.freefireth", "com.dts.freefiremax", From d0f0aad52ef44d01bf0f4bea60d3bac793ed4f4f Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Fri, 14 Jun 2024 09:49:40 -0600 Subject: [PATCH 72/79] Fix SwiftLint and disable SwiftLint non_optional_string_data_conversion (#1514) * Fix Opening Brace Spacing Violation * Disable SwiftLint rule non_optional_string_data_conversion --- .swiftlint.yml | 4 ++++ .../Genshin Account Views/ChangeGenshinAccountView.swift | 2 +- .../Genshin Account Views/DeleteGenshinAccountView.swift | 2 +- .../Views/Genshin Account Views/StoreGenshinAccountView.swift | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 52db4316a..4fdd6f026 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -11,3 +11,7 @@ identifier_name: type_name: allowed_symbols: ['_'] + +disabled_rules: + # see https://github.com/realm/SwiftLint/issues/5263 + - non_optional_string_data_conversion diff --git a/PlayCover/Views/Genshin Account Views/ChangeGenshinAccountView.swift b/PlayCover/Views/Genshin Account Views/ChangeGenshinAccountView.swift index e8b8b11c9..91c386b61 100644 --- a/PlayCover/Views/Genshin Account Views/ChangeGenshinAccountView.swift +++ b/PlayCover/Views/Genshin Account Views/ChangeGenshinAccountView.swift @@ -22,7 +22,7 @@ struct ChangeGenshinAccountView: View { Text("storeAccount.selectAcc").font(.largeTitle).lineLimit(1).fixedSize() Spacer() ForEach(filteredList, id: \.self) { account in - if account != ".DS_Store"{ + if account != ".DS_Store" { Button(action: { self.folderName = account self.restoreAlert = true diff --git a/PlayCover/Views/Genshin Account Views/DeleteGenshinAccountView.swift b/PlayCover/Views/Genshin Account Views/DeleteGenshinAccountView.swift index 960deaa79..7e9ba8f0c 100644 --- a/PlayCover/Views/Genshin Account Views/DeleteGenshinAccountView.swift +++ b/PlayCover/Views/Genshin Account Views/DeleteGenshinAccountView.swift @@ -18,7 +18,7 @@ struct DeleteGenshinAccountView: View { Text("storeAccount.deleteAcc").font(.largeTitle).lineLimit(1).fixedSize() Spacer() ForEach(accountList, id: \.self) { account in - if account != ".DS_Store"{ + if account != ".DS_Store" { Button(action: { self.folderName = account self.deleteAlert = true diff --git a/PlayCover/Views/Genshin Account Views/StoreGenshinAccountView.swift b/PlayCover/Views/Genshin Account Views/StoreGenshinAccountView.swift index fcb4b3762..3b3ae96cd 100644 --- a/PlayCover/Views/Genshin Account Views/StoreGenshinAccountView.swift +++ b/PlayCover/Views/Genshin Account Views/StoreGenshinAccountView.swift @@ -19,7 +19,7 @@ struct StoreGenshinAccountView: View { Spacer() Text("storeAccount.storeAcc").font(.largeTitle).lineLimit(1).fixedSize() Spacer() - if app.info.bundleIdentifier == "com.miHoYo.GenshinImpact"{ + if app.info.bundleIdentifier == "com.miHoYo.GenshinImpact" { HStack(spacing: 0) { Picker(selection: $selectedRegion, label: Text("storeAccount.selectAccRegion") From 73e4e2e0b8cfeed282f6d6e88a340264e94c5e03 Mon Sep 17 00:00:00 2001 From: Mitchell Mebane Date: Wed, 26 Jun 2024 22:38:15 -0500 Subject: [PATCH 73/79] Make notch detection work without hard-coded model list --- PlayCover/Model/AppSettings.swift | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/PlayCover/Model/AppSettings.swift b/PlayCover/Model/AppSettings.swift index 97213ba2b..900c763e6 100644 --- a/PlayCover/Model/AppSettings.swift +++ b/PlayCover/Model/AppSettings.swift @@ -148,15 +148,11 @@ class AppSettings { } } -let notchModels = ["MacBookPro18,3", "MacBookPro18,4", "MacBookPro18,1", "MacBookPro18,2", "Mac14,2"] - extension NSScreen { public static func hasNotch() -> Bool { - if let model = NSScreen.getMacModel() { - return notchModels.contains(model) - } else { - return false - } + guard #available(macOS 12, *) else { return false } + // check if any of the connected screens contains a notch + return NSScreen.screens.contains { $0.safeAreaInsets.top != 0 } } private static func getMacModel() -> String? { From 68c9216939b86da0e2ddd0065237f4253a6738ff Mon Sep 17 00:00:00 2001 From: Adam C <66894537+Wind-Explorer@users.noreply.github.com> Date: Sat, 29 Jun 2024 06:26:44 +0800 Subject: [PATCH 74/79] Added store app icon load timeout (#1207) * Added store app icon load timeout --- PlayCover/Views/App Views/StoreAppView.swift | 30 ++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/PlayCover/Views/App Views/StoreAppView.swift b/PlayCover/Views/App Views/StoreAppView.swift index fdb7f49e0..1cd2ca4f5 100644 --- a/PlayCover/Views/App Views/StoreAppView.swift +++ b/PlayCover/Views/App Views/StoreAppView.swift @@ -76,6 +76,7 @@ struct StoreAppConditionalView: View { @State var itunesResponse: ITunesResponse? @State var onlineIcon: URL? @State var localIcon: NSImage? + @State var loadingLocalIcon: Bool = true @State var isList: Bool @Binding var warningSymbol: String? @@ -85,6 +86,12 @@ struct StoreAppConditionalView: View { @State private var cache = DataCache.instance + @Sendable private func waitForIconLoad() async { + loadingLocalIcon = true + try? await Task.sleep(nanoseconds: 6_000_000_000) + loadingLocalIcon = false + } + var body: some View { Group { if isList { @@ -107,10 +114,16 @@ struct StoreAppConditionalView: View { Rectangle() .fill(.regularMaterial) .overlay { - ProgressView() - .progressViewStyle(.circular) - .controlSize(.small) + if loadingLocalIcon { + ProgressView() + .progressViewStyle(.circular) + .controlSize(.small) + } else { + Image(systemName: "exclamationmark.triangle") + .opacity(0.5) + } } + .task(self.waitForIconLoad) } } } @@ -154,9 +167,16 @@ struct StoreAppConditionalView: View { Rectangle() .fill(.regularMaterial) .overlay { - ProgressView() - .progressViewStyle(.circular) + if loadingLocalIcon { + ProgressView() + .progressViewStyle(.circular) + } else { + Image(systemName: "exclamationmark.triangle") + .font(.system(size: 24)) + .opacity(0.5) + } } + .task(self.waitForIconLoad) } } } From a14960e031fb703ca0e07a1d376a52623db5e0f6 Mon Sep 17 00:00:00 2001 From: TheMoonThatRises <58153205+TheMoonThatRises@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:44:26 -0600 Subject: [PATCH 75/79] IPA library app info (#1176) * feat: ipa library app info * remove duplicate localisations --- PlayCover.xcodeproj/project.pbxproj | 8 + PlayCover/ViewModel/NetworkVM.swift | 23 ++- PlayCover/ViewModel/StoreAppVM.swift | 16 ++ PlayCover/Views/App Views/StoreAppView.swift | 14 +- PlayCover/Views/MainView.swift | 3 +- .../Views/Sidebar Views/IPALibraryView.swift | 19 ++ PlayCover/Views/StoreInfoAppView.swift | 176 ++++++++++++++++++ PlayCover/en.lproj/Localizable.strings | 8 + 8 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 PlayCover/ViewModel/StoreAppVM.swift create mode 100644 PlayCover/Views/StoreInfoAppView.swift diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index de52000da..489a812fc 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -85,6 +85,8 @@ B17FD04728C7B0D900B1D4CA /* AssetsExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17FD04628C7B0D900B1D4CA /* AssetsExtractor.swift */; }; B6603E1128E206A300DEFA3F /* UninstallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1028E206A300DEFA3F /* UninstallSettings.swift */; }; B6603E1328E2257800DEFA3F /* Uninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1228E2257800DEFA3F /* Uninstaller.swift */; }; + B67C1A112AE8091F00F396CC /* StoreInfoAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67C1A102AE8091F00F396CC /* StoreInfoAppView.swift */; }; + B67C1A132AE80A7400F396CC /* StoreAppVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67C1A122AE80A7400F396CC /* StoreAppVM.swift */; }; B6825C3528F3D23600E3015A /* InstallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6825C3428F3D23600E3015A /* InstallSettings.swift */; }; B68FD80D2ACB642100683778 /* PlayAppExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68FD80C2ACB642100683778 /* PlayAppExtensions.swift */; }; B6AB53C929232B4F00039B2E /* KeyCodeNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AB53C829232B4F00039B2E /* KeyCodeNames.swift */; }; @@ -192,6 +194,8 @@ B490E8692C0D0E8A004383FA /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; B6603E1028E206A300DEFA3F /* UninstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UninstallSettings.swift; sourceTree = ""; }; B6603E1228E2257800DEFA3F /* Uninstaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Uninstaller.swift; sourceTree = ""; }; + B67C1A102AE8091F00F396CC /* StoreInfoAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreInfoAppView.swift; sourceTree = ""; }; + B67C1A122AE80A7400F396CC /* StoreAppVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreAppVM.swift; sourceTree = ""; }; B6825C3428F3D23600E3015A /* InstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallSettings.swift; sourceTree = ""; }; B68FD80C2ACB642100683778 /* PlayAppExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayAppExtensions.swift; sourceTree = ""; }; B6AB53C829232B4F00039B2E /* KeyCodeNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCodeNames.swift; sourceTree = ""; }; @@ -238,6 +242,7 @@ 6E66B0D428A0039D0099B907 /* ToastView.swift */, 365AFB0728847B75008B3542 /* Sparkle.swift */, 6ED6ACA328A949A30040D234 /* AppSettingsView.swift */, + B67C1A102AE8091F00F396CC /* StoreInfoAppView.swift */, 6E250970297F5281004D754C /* SigningSetupView.swift */, 6E06193428B3C3ED0012C771 /* Genshin Account Views */, 6E66B0CF289F562A0099B907 /* Sidebar Views */, @@ -310,6 +315,7 @@ 6E66B0D828A135360099B907 /* ToastVM.swift */, 53F4D29F26C43C690020167C /* Log.swift */, B6ABDA292971EEF700A46E80 /* ProgressVM.swift */, + B67C1A122AE80A7400F396CC /* StoreAppVM.swift */, ); path = ViewModel; sourceTree = ""; @@ -655,6 +661,7 @@ 6E550A8B29BA507200EFC15C /* Macho.swift in Sources */, 6E25096F297F5032004D754C /* FileExtensions.swift in Sources */, 53F4D2A026C43C690020167C /* Log.swift in Sources */, + B67C1A132AE80A7400F396CC /* StoreAppVM.swift in Sources */, B6603E1128E206A300DEFA3F /* UninstallSettings.swift in Sources */, 92A8AAC9275EFEA800D89B50 /* SystemConfig.swift in Sources */, 6E66B0C9289F52800099B907 /* IPALibraryView.swift in Sources */, @@ -694,6 +701,7 @@ ABED59832887A32F004D782B /* MenuBarView.swift in Sources */, B6AB53C929232B4F00039B2E /* KeyCodeNames.swift in Sources */, 92EE06D4274EA604002C907B /* PlayAppView.swift in Sources */, + B67C1A112AE8091F00F396CC /* StoreInfoAppView.swift in Sources */, 6E21233128F65F7600B4D75D /* GenshinUserDataURLs.swift in Sources */, B17FD04728C7B0D900B1D4CA /* AssetsExtractor.swift in Sources */, ABDAD80629893CF900DC164F /* KeyCoverSetupViews.swift in Sources */, diff --git a/PlayCover/ViewModel/NetworkVM.swift b/PlayCover/ViewModel/NetworkVM.swift index 7dbebee2e..7e639082a 100644 --- a/PlayCover/ViewModel/NetworkVM.swift +++ b/PlayCover/ViewModel/NetworkVM.swift @@ -58,15 +58,18 @@ class NetworkVM { }) } - static func urlAccessible(url: URL, popup: Bool = false) -> (URL?, Bool) { + static func urlAccessible(url: URL, + popup: Bool = false, + completion: ((URL?, Bool) -> Void)? = nil) -> (URL?, Bool) { guard isConnectedToNetwork() else { + completion?(nil, false) return (nil, false) } let semaphore = DispatchSemaphore(value: 0) let validStatusCodes = [200, 301, 302, 303, 307, 308] - var avaliable = false + var available = false var finalURL: URL? var request = URLRequest(url: url) @@ -75,22 +78,30 @@ class NetworkVM { URLSession.shared.dataTask(with: request) { _, response, error in defer { semaphore.signal() } if let error = error { - Log.shared.error(error) + if popup { + Log.shared.error(error) + } else { + Log.shared.log(error.localizedDescription, isError: true) + } } else { if let httpResponse = response as? HTTPURLResponse { if validStatusCodes.contains(httpResponse.statusCode) { finalURL = httpResponse.url - avaliable = true + available = true } else if popup { Log.shared.error("Unable to download: \(httpResponse.statusCode) " + "\(HTTPURLResponse.localizedString(forStatusCode: httpResponse.statusCode))") } } } + + completion?(finalURL, available) }.resume() - semaphore.wait() + if completion == nil { + semaphore.wait() + } - return (finalURL, avaliable) + return (finalURL, available) } } diff --git a/PlayCover/ViewModel/StoreAppVM.swift b/PlayCover/ViewModel/StoreAppVM.swift new file mode 100644 index 000000000..414ed50f0 --- /dev/null +++ b/PlayCover/ViewModel/StoreAppVM.swift @@ -0,0 +1,16 @@ +// +// StoreAppVM.swift +// PlayCover +// +// Created by TheMoonThatRises on 10/24/23. +// + +import Foundation + +class StoreAppVM: ObservableObject { + @Published var data: StoreAppData + + init(data: StoreAppData) { + self.data = data + } +} diff --git a/PlayCover/Views/App Views/StoreAppView.swift b/PlayCover/Views/App Views/StoreAppView.swift index 1cd2ca4f5..7c0f6476c 100644 --- a/PlayCover/Views/App Views/StoreAppView.swift +++ b/PlayCover/Views/App Views/StoreAppView.swift @@ -17,6 +17,7 @@ struct StoreAppView: View { @State var app: StoreAppData @State var isList: Bool @State var observation: NSKeyValueObservation? + @State var showInfo = false @State var warningSymbol: String? @State var warningMessage: String? @@ -42,9 +43,20 @@ struct StoreAppView: View { } } }) + .contextMenu { + Button(action: { + showInfo.toggle() + }, label: { + Text("ipaLibrary.info") + }) + } .simultaneousGesture(TapGesture().onEnded { selected = app }) + .sheet(isPresented: $showInfo) { + StoreInfoAppView(viewModel: StoreAppVM(data: app)) + .environmentObject(downloadVM) + } .environmentObject(downloadVM) .task(priority: .background) { if let sourceApp = AppsVM.shared.apps.first(where: { $0.info.bundleIdentifier == app.bundleID }) { @@ -211,7 +223,7 @@ struct StoreAppConditionalView: View { .frame(width: 130, height: 130) } } - .task(priority: .userInitiated) { + .task(priority: .background) { if !cache.hasData(forKey: app.itunesLookup) { await Cacher().resolveITunesData(app.itunesLookup) } diff --git a/PlayCover/Views/MainView.swift b/PlayCover/Views/MainView.swift index c14e03e95..62b38f08e 100644 --- a/PlayCover/Views/MainView.swift +++ b/PlayCover/Views/MainView.swift @@ -39,7 +39,8 @@ struct MainView: View { } NavigationLink(destination: IPALibraryView(selectedBackgroundColor: $selectedBackgroundColor, selectedTextColor: $selectedTextColor) - .environmentObject(store), + .environmentObject(store) + .environmentObject(DownloadVM.shared), tag: 2, selection: self.$selectedView) { Label("sidebar.ipaLibrary", systemImage: "arrow.down.circle") } diff --git a/PlayCover/Views/Sidebar Views/IPALibraryView.swift b/PlayCover/Views/Sidebar Views/IPALibraryView.swift index 90502a979..928246092 100644 --- a/PlayCover/Views/Sidebar Views/IPALibraryView.swift +++ b/PlayCover/Views/Sidebar Views/IPALibraryView.swift @@ -9,6 +9,7 @@ import SwiftUI struct IPALibraryView: View { @EnvironmentObject var storeVM: StoreVM + @EnvironmentObject var downloadVM: DownloadVM @Binding var selectedBackgroundColor: Color @Binding var selectedTextColor: Color @@ -18,6 +19,7 @@ struct IPALibraryView: View { @State private var isList = UserDefaults.standard.bool(forKey: "IPALibraryView") @State private var selected: StoreAppData? @State private var addSourcePresented = false + @State private var showInfo = false @ObservedObject private var URLObserved = URLObservable.shared @@ -89,6 +91,17 @@ struct IPALibraryView: View { } .navigationTitle("sidebar.ipaLibrary") .toolbar { + ToolbarItem(placement: .primaryAction) { + Button(action: { + showInfo.toggle() + }, label: { + Image(systemName: "info.circle") + }) + .disabled(selected == nil) + } + ToolbarItem(placement: .primaryAction) { + Spacer() + } ToolbarItem(placement: .primaryAction) { Button(action: { storeVM.resolveSources() @@ -134,6 +147,12 @@ struct IPALibraryView: View { AddSourceView(addSourceSheet: $addSourcePresented) .environmentObject(storeVM) } + .sheet(isPresented: $showInfo) { + if let selected = selected { + StoreInfoAppView(viewModel: StoreAppVM(data: selected)) + .environmentObject(downloadVM) + } + } .onChange(of: URLObserved.type) {_ in addSourcePresented = URLObserved.type == .source } diff --git a/PlayCover/Views/StoreInfoAppView.swift b/PlayCover/Views/StoreInfoAppView.swift new file mode 100644 index 000000000..040e1740e --- /dev/null +++ b/PlayCover/Views/StoreInfoAppView.swift @@ -0,0 +1,176 @@ +// +// StoreInfoAppView.swift +// PlayCover +// +// Created by TheMoonThatRises on 10/24/23. +// + +import SwiftUI +import DataCache +import CachedAsyncImage + +struct StoreInfoAppView: View { + @Environment(\.dismiss) var dismiss + + @EnvironmentObject var downloadVM: DownloadVM + + @ObservedObject var viewModel: StoreAppVM + + @State var closeView = false + + @State var isAvailable: Bool? + @State var onlineIcon: URL? + @State var localIcon: NSImage? + + @State var itunesResponse: ITunesResponse? + + @State private var cache = DataCache.instance + + var body: some View { + VStack { + HStack { + ZStack { + Group { + CachedAsyncImage(url: onlineIcon, urlCache: .iconCache) { image in + image + .resizable() + .aspectRatio(contentMode: .fit) + } placeholder: { + if let image = localIcon { + Image(nsImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + } else { + Rectangle() + .fill(.regularMaterial) + .overlay { + ProgressView() + .progressViewStyle(.circular) + .controlSize(.small) + } + } + } + } + .cornerRadius(10) + .shadow(radius: 1) + .frame(width: 33, height: 33) + if downloadVM.inProgress && downloadVM.storeAppData == viewModel.data { + ProgressView(value: downloadVM.progress) + .progressViewStyle(.circular) + } + } + + VStack { + HStack { + Text(String( + format: + NSLocalizedString("ipaLibrary.info.title", comment: ""), + viewModel.data.name)) + .font(.title2).bold() + .multilineTextAlignment(.leading) + Spacer() + } + + let notAvailableWarning = Image(systemName: "exclamationmark.triangle") + let warning = NSLocalizedString("ipaLibrary.info.notAvailable", comment: "") + + if !(isAvailable ?? true) { + HStack { + Text("\(notAvailableWarning) \(warning)") + .font(.caption) + .multilineTextAlignment(.leading) + Spacer() + } + } + } + } + + TabView { + StoreInfoView(data: $viewModel.data) + .tabItem { + Text("settings.tab.info") + } + } + .frame(minWidth: 500, minHeight: 250) + HStack { + Spacer() + Button("button.OK") { + closeView.toggle() + } + .tint(.accentColor) + .keyboardShortcut(.defaultAction) + } + } + .onChange(of: closeView) { _ in + dismiss() + } + .task(priority: .background) { + if let link = URL(string: viewModel.data.link) { + _ = NetworkVM.urlAccessible(url: link, popup: false) { _, available in + isAvailable = available + } + } else { + isAvailable = false + } + + if !cache.hasData(forKey: viewModel.data.itunesLookup) { + await Cacher().resolveITunesData(viewModel.data.itunesLookup) + } + itunesResponse = try? cache.readCodable(forKey: viewModel.data.itunesLookup) + if let response = itunesResponse { + onlineIcon = URL(string: response.results[0].artworkUrl512) + } else { + localIcon = Cacher().getLocalIcon(bundleId: viewModel.data.bundleID) + } + } + .padding() + } + +} + +struct StoreInfoView: View { + + @Binding var data: StoreAppData + + var body: some View { + List { + HStack { + Text("settings.info.bundleName") + Spacer() + Text("\(data.name)") + } + HStack { + Text("settings.info.bundleIdentifier") + Spacer() + Text("\(data.bundleID)") + } + HStack { + Text("settings.info.bundleVersion") + Spacer() + Text("\(data.version)") + } + HStack { + Text("ipaLibrary.info.itunes") + Spacer() + Text(.init("[\(data.itunesLookup)](\(data.itunesLookup))")) + } + HStack { + Text("settings.info.url") + Spacer() + Text(.init("[\(data.link)](\(data.link))")) + } + HStack { + Text("ipaLibrary.info.checksum") + Spacer() + if let checksum = data.checksum { + Text("\(checksum)") + } else { + Text("ipaLibrary.info.checksum.none") + } + } + } + .listStyle(.bordered(alternatesRowBackgrounds: true)) + .padding() + } + +} diff --git a/PlayCover/en.lproj/Localizable.strings b/PlayCover/en.lproj/Localizable.strings index ed093a509..abda28b29 100644 --- a/PlayCover/en.lproj/Localizable.strings +++ b/PlayCover/en.lproj/Localizable.strings @@ -20,6 +20,13 @@ "playapp.noSources.title" = "No IPAs Installed"; "playapp.noSources.subtitle" = "You currently have no IPAs installed. Click the button below to import one."; +"ipaLibrary.info" = "App Info"; +"ipaLibrary.info.title" = "%@ Info"; +"ipaLibrary.info.notAvailable" = "Link not valid for this app"; +"ipaLibrary.info.itunes" = "ITunes Lookup:"; +"ipaLibrary.info.checksum" = "Checksum:"; +"ipaLibrary.info.checksum.none" = "None provided"; + "ipaLibrary.noSources.title" = "No IPA Sources Added"; "ipaLibrary.noSources.subtitle" = "You currently have no IPA Sources added. Click the button below to add one."; "ipaLibrary.noSources.button" = "Add Source"; @@ -28,6 +35,7 @@ "ipaLibrary.version.older" = "This version is older than the one you have installed"; "ipaLibrary.version.same" = "App already installed"; "ipaLibrary.version.newer" = "This version is newer than the version you have installed"; +"ipaLibrary.unavailable" = "The link is unavailable"; "ipaLibrary.alert.download" = "Are you sure you want to download this version of %@?"; "ipaLibrary.download" = "Download"; From bc751d6ad97c4ea80ab2dbcf63e1e9e38ad0bdf9 Mon Sep 17 00:00:00 2001 From: Sinon <34333654+Catta1997@users.noreply.github.com> Date: Sun, 30 Jun 2024 19:27:41 +0200 Subject: [PATCH 76/79] Google drive hosted IPA (#1472) * Google Drive hosted IPA * Rebase * Fix Compile Error * completionHandler and dispatchGroup Find a better way (maybe still not the best) to wait redirect and scripting to end * Moved redirectHendler Moved functions to StoreAppView and reverted "url" variable to "let" * fix project GD file Error fixed also format error * Delete all changes on Downloader.swift * Moved GoogleDrive.swift * add timeout on GD requests * fix missing file from repo * fix carthage (again) * fix build (again) * required modification * Removed (null) files reference and fixed swiftlint * Added SwiftSoup to Package Dependencies * Change SwiftSoup version this should fix build error * Revert change to cartfile files * Access modifiers changes Making all variable and function private * Added support for personal drive Added support for shared link for personal google drive IPA ( Link must be like "https://drive.google.com/file/d/FILE_ID/view?usp=share_link" ) * Changes - support to https://drive.usercontent.google.com/download?id={FileID}&export=download - changed SwiftSoup to a lighter forked version --- PlayCover.xcodeproj/project.pbxproj | 21 +++ PlayCover/Utils/GoogleDrive.swift | 144 +++++++++++++++++++ PlayCover/Views/App Views/StoreAppView.swift | 3 +- 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 PlayCover/Utils/GoogleDrive.swift diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 489a812fc..29f8aeee7 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -83,6 +83,8 @@ B1419FB628BA82EE000CB69F /* DiscordActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1419FB528BA82EE000CB69F /* DiscordActivity.swift */; }; B17FD03C28C70C2100B1D4CA /* CoreUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B17FD03828C70BAE00B1D4CA /* CoreUI.framework */; }; B17FD04728C7B0D900B1D4CA /* AssetsExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17FD04628C7B0D900B1D4CA /* AssetsExtractor.swift */; }; + B44B40372C1E315600CE2A3E /* GoogleDrive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B44B40362C1E315600CE2A3E /* GoogleDrive.swift */; }; + B44E8CD32C31C50200542038 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = B44E8CD22C31C50200542038 /* SwiftSoup */; }; B6603E1128E206A300DEFA3F /* UninstallSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1028E206A300DEFA3F /* UninstallSettings.swift */; }; B6603E1328E2257800DEFA3F /* Uninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6603E1228E2257800DEFA3F /* Uninstaller.swift */; }; B67C1A112AE8091F00F396CC /* StoreInfoAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67C1A102AE8091F00F396CC /* StoreInfoAppView.swift */; }; @@ -191,6 +193,7 @@ B17FD03828C70BAE00B1D4CA /* CoreUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreUI.framework; path = /System/Library/PrivateFrameworks/CoreUI.framework; sourceTree = ""; }; B17FD03F28C70C7300B1D4CA /* CoreUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreUI.h; sourceTree = ""; }; B17FD04628C7B0D900B1D4CA /* AssetsExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetsExtractor.swift; sourceTree = ""; }; + B44B40362C1E315600CE2A3E /* GoogleDrive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GoogleDrive.swift; path = PlayCover/Utils/GoogleDrive.swift; sourceTree = SOURCE_ROOT; }; B490E8692C0D0E8A004383FA /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; B6603E1028E206A300DEFA3F /* UninstallSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UninstallSettings.swift; sourceTree = ""; }; B6603E1228E2257800DEFA3F /* Uninstaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Uninstaller.swift; sourceTree = ""; }; @@ -212,6 +215,7 @@ 365AFB0628847B2E008B3542 /* Sparkle in Frameworks */, 68E48BA229570A2B00C39879 /* CachedAsyncImage in Frameworks */, AA818CB5287ABEC3000BEE9D /* Yams in Frameworks */, + B44E8CD32C31C50200542038 /* SwiftSoup in Frameworks */, 68E48B952957046D00C39879 /* DownloadManager in Frameworks */, B17FD03C28C70C2100B1D4CA /* CoreUI.framework in Frameworks */, ); @@ -325,6 +329,7 @@ children = ( 6E25096D297F4E95004D754C /* Extensions */, 6E21232F28F65F5800B4D75D /* GenshinUserData */, + B44B40362C1E315600CE2A3E /* GoogleDrive.swift */, 92ECD8A4274E763700DB7AC6 /* IPA.swift */, 92EE06DD274EC09F002C907B /* Entitlements.swift */, 5314D1ED26C402EC00A0A727 /* Shell.swift */, @@ -478,6 +483,7 @@ 68E48B9E29570A0400C39879 /* DataCache */, 68E48BA129570A2B00C39879 /* CachedAsyncImage */, 68E48B99295708C800C39879 /* Injection */, + B44E8CD22C31C50200542038 /* SwiftSoup */, ); productName = PlayCover; productReference = 8783CFF726B8C52D00171041 /* PlayCover.app */; @@ -533,6 +539,7 @@ 68E48B9D29570A0400C39879 /* XCRemoteSwiftPackageReference "DataCache" */, 68E48BA029570A2B00C39879 /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */, 68E48B98295708C800C39879 /* XCRemoteSwiftPackageReference "inject" */, + B44E8CD12C31C50200542038 /* XCRemoteSwiftPackageReference "SwiftSoup" */, ); productRefGroup = 8783CFF826B8C52D00171041 /* Products */; projectDirPath = ""; @@ -684,6 +691,7 @@ 92EE06D0274EA433002C907B /* BaseApp.swift in Sources */, ABBC85B92B7C5CBA00DCF223 /* ModifierKeyObserver.swift in Sources */, 92F8500A27675124005CE6BE /* AppIntegrity.swift in Sources */, + B44B40372C1E315600CE2A3E /* GoogleDrive.swift in Sources */, 6E06193828B3C4240012C771 /* ChangeGenshinAccountView.swift in Sources */, 68E48B97295704A600C39879 /* Downloader.swift in Sources */, 28361D5E2892781200B35EDB /* RestoreGenshinUserData.swift in Sources */, @@ -1028,6 +1036,14 @@ minimumVersion = 5.0.0; }; }; + B44E8CD12C31C50200542038 /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/PlayCover/SwiftSoup"; + requirement = { + kind = revision; + revision = 6d808c0522471d9f8892c85601164ed5b462f8c0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1061,6 +1077,11 @@ package = AA818CB3287ABEC3000BEE9D /* XCRemoteSwiftPackageReference "Yams" */; productName = Yams; }; + B44E8CD22C31C50200542038 /* SwiftSoup */ = { + isa = XCSwiftPackageProductDependency; + package = B44E8CD12C31C50200542038 /* XCRemoteSwiftPackageReference "SwiftSoup" */; + productName = SwiftSoup; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 8783CFEF26B8C52D00171041 /* Project object */; diff --git a/PlayCover/Utils/GoogleDrive.swift b/PlayCover/Utils/GoogleDrive.swift new file mode 100644 index 000000000..d8da6c865 --- /dev/null +++ b/PlayCover/Utils/GoogleDrive.swift @@ -0,0 +1,144 @@ +// +// GoogleDrive.swift +// PlayCover +// +// Created by Edoardo C. on 16/05/24. +// + +import Foundation +import SwiftSoup + +class RedirectHandler: NSObject, URLSessionTaskDelegate { + private var finalURL: URL + private let dispatchGroup = DispatchGroup() // DispatchGroup + private var completion: (() -> Void)? // completion handler + lazy var session: URLSession = { + let configuration = URLSessionConfiguration.default + return URLSession(configuration: configuration, delegate: self, delegateQueue: nil) + }() + init(url: URL) { + self.finalURL = url + super.init() + if url.absoluteString.contains("drive.google.com") { + if let myurl = self.convertGoogleDriveLink(url.absoluteString) { + self.scrapeWebsite(from: URLRequest(url: myurl)) + } + } else if url.absoluteString.contains("drive.usercontent.google.com") { + self.scrapeWebsite(from: URLRequest(url: url)) + } else { + self.redirectCatch(from: url) + } + self.waitForAllTasksToComplete() + } + func getFinal() -> URL { + return finalURL + } + private func setFinal(url: URL) { + self.finalURL = url + } + private func fetchGoogleDrivePageContent(url: String, completion: @escaping (String?) -> Void) { + guard let url = URL(string: url) else { + completion(nil) + return + } + dispatchGroup.enter() // Enter Group + let task = session.dataTask(with: url) { data, _, error in + defer { self.dispatchGroup.leave() } // Leave group + guard let data = data, error == nil else { + completion(nil) + return + } + let htmlContent = String(data: data, encoding: .utf8) + completion(htmlContent) + } + task.resume() + } + private func extractDownloadLink(from htmlContent: String) { + do { + let doc = try SwiftSoup.parse(htmlContent) + guard let form = try doc.select("form#download-form").first() else { + return + } + let action = try form.attr("action") + let id = try form.select("input[name=id]").attr("value") + let confirm = try form.select("input[name=confirm]").attr("value") + let uuid = try form.select("input[name=uuid]").attr("value") + let directDownloadLink = "\(action)?id=\(id)&confirm=\(confirm)&uuid=\(uuid)" + let url = URL(string: directDownloadLink) + if let url = url { + setFinal(url: url) + } + } catch { + return + } + } + private func convertGoogleDriveLink(_ originalLink: String) -> URL? { + guard let fileIdRange = originalLink.range(of: "/file/d/") else { + return nil + } + let startIndex = fileIdRange.upperBound + guard let endIndex = originalLink[startIndex...].firstIndex(of: "/") else { + return nil + } + let fileId = originalLink[startIndex.. Void) { + self.completion = completion + fetchGoogleDrivePageContent(url: googleDriveLink) { htmlContent in + guard htmlContent != nil else { + return + } + completion() + } + } + private func redirectCatch(from url: URL) { + dispatchGroup.enter() // Enter group + let task = session.dataTask(with: url) { _, _, error in + defer { self.dispatchGroup.leave() } // Exit from the group at end of task + if error != nil { + return + } + } + task.resume() + } + private func scrapeWebsite(from request: URLRequest) { + dispatchGroup.enter() // Enter group + let task = session.dataTask(with: request) { data, _, error in + defer { self.dispatchGroup.leave() } // Exit from the group at end of task + if error != nil { + return + } + if let data = data, let html = String(data: data, encoding: .utf8) { + self.extractDownloadLink(from: html) + } + } + task.resume() + } + // Handle redirects manually + func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, + newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { + if let redirectURL = request.url { + if let url = self.convertGoogleDriveLink(redirectURL.absoluteString) { + var newRequest = URLRequest(url: url) + newRequest.httpMethod = "GET" + newRequest.setValue(""" + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) + Chrome/124.0.0.0 Safari/537.36 + """, forHTTPHeaderField: "User-Agent") + self.scrapeWebsite(from: newRequest) + completionHandler(nil) + } else { + completionHandler(nil) + } + } else { + completionHandler(nil) + } + } + // Wait URL Session + private func waitForAllTasksToComplete() { + let timeout = DispatchTime.now() + DispatchTimeInterval.seconds(5) + _ = dispatchGroup.wait(timeout: timeout) + } +} diff --git a/PlayCover/Views/App Views/StoreAppView.swift b/PlayCover/Views/App Views/StoreAppView.swift index 7c0f6476c..4e078cf68 100644 --- a/PlayCover/Views/App Views/StoreAppView.swift +++ b/PlayCover/Views/App Views/StoreAppView.swift @@ -38,7 +38,8 @@ struct StoreAppView: View { if downloadVM.inProgress { Log.shared.error(PlayCoverError.waitDownload) } else { - DownloadApp(url: url, app: app, + let redirectHandler = RedirectHandler(url: url) // checking page redirect + DownloadApp(url: redirectHandler.getFinal(), app: app, warning: warningMessage).start() } } From 90d9028833e4fe10a577ec33e89e6ac9e637d984 Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Mon, 1 Jul 2024 10:13:54 -0600 Subject: [PATCH 77/79] Update clearPlayChain (#1499) Add DB files to clearPlayChain as introduced in https://github.com/PlayCover/PlayTools/pull/140 --- PlayCover/Model/PlayApp.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/PlayCover/Model/PlayApp.swift b/PlayCover/Model/PlayApp.swift index 528089b18..a77c03224 100644 --- a/PlayCover/Model/PlayApp.swift +++ b/PlayCover/Model/PlayApp.swift @@ -264,6 +264,7 @@ class PlayApp: BaseApp { func clearPlayChain() { FileManager.default.delete(at: playChainURL) FileManager.default.delete(at: playChainURL.appendingPathExtension("keyCover")) + FileManager.default.delete(at: playChainURL.appendingPathExtension("db")) } func deleteApp() { From 7ff0e391e4ecab4386d37856fae20ba5bdc8ddd1 Mon Sep 17 00:00:00 2001 From: FlyMeToTheMoonAndLetMePlayAmongTheStars <78054566+FlyMeToTheMoonAndLetMePlayAmongTheStars@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:50:12 -0400 Subject: [PATCH 78/79] Add support for iPhone 15 Pro Max and 13" M4 iPad Pro (#1470) * Add support for iPhone 15 Pro Max and 13" M4 iPad Pro * Change RAM iPad M4 --------- Co-authored-by: Depal1 <47154119+Depal1@users.noreply.github.com> --- PlayCover/Views/AppSettingsView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PlayCover/Views/AppSettingsView.swift b/PlayCover/Views/AppSettingsView.swift index 454333208..aeda4f220 100644 --- a/PlayCover/Views/AppSettingsView.swift +++ b/PlayCover/Views/AppSettingsView.swift @@ -219,9 +219,11 @@ struct GraphicsView: View { Text("iPad Pro (12.9-inch) (3rd gen) | A12X | 4GB").tag("iPad8,6") Text("iPad Pro (12.9-inch) (5th gen) | M1 | 8GB").tag("iPad13,8") Text("iPad Pro (12.9-inch) (6th gen) | M2 | 8GB").tag("iPad14,5") + Text("iPad Pro (13-inch) (7th gen) | M4 | 8GB").tag("iPad16,6") Divider() Text("iPhone 13 Pro Max | A15 | 6GB").tag("iPhone14,3") Text("iPhone 14 Pro Max | A16 | 6GB").tag("iPhone15,3") + Text("iPhone 15 Pro Max | A17 Pro | 8GB").tag("iPhone16,2") } .frame(width: 250) } From a9cd5ff2c3f768fba6ce6394f7a21f577f7cd88b Mon Sep 17 00:00:00 2001 From: Depal1 <47154119+Depal1@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:30:25 -0600 Subject: [PATCH 79/79] PlayTools v3.0.0 and Build Number Bump (#1541) --- Cartfile.resolved | 2 +- PlayCover.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index db246e4db..1eaee7b53 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "PlayCover/PlayTools" "v3.0.0-beta.2" +github "PlayCover/PlayTools" "v3.0.0" diff --git a/PlayCover.xcodeproj/project.pbxproj b/PlayCover.xcodeproj/project.pbxproj index 29f8aeee7..6f4adbda9 100644 --- a/PlayCover.xcodeproj/project.pbxproj +++ b/PlayCover.xcodeproj/project.pbxproj @@ -830,7 +830,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 233; + CURRENT_PROJECT_VERSION = 793; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content"; @@ -933,7 +933,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 233; + CURRENT_PROJECT_VERSION = 793; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "PlayCover/Preview\\ Content";