├── .editorconfig
├── .github
├── dependabot.yml
└── workflows
│ ├── merge-conflict-auto-label.yml
│ ├── push-test.yml
│ └── release.yml
├── .gitignore
├── .vscode
├── extensions.json
└── tasks.json
├── LICENSE
├── README.md
├── docs
├── DEV-TOOLS.md
├── DEVELOPMENT.md
├── FAQ.md
├── TROUBLESHOOTING.md
├── assets
│ ├── Square310x310Logo.png
│ ├── dev-view-screenshot.png
│ ├── downloadbutton.png
│ ├── flightcore-webview2-windows-error-message.png
│ ├── flightcore.svg
│ ├── main-window-screenshot.png
│ └── webview2-download-screenshot.png
└── index.html
├── package-lock.json
├── package.json
├── scripts
├── check_version_numbers.py
└── create-release-file.py
├── src-tauri
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── bindings
│ ├── CommitHead.ts
│ ├── FlightCoreVersion.ts
│ ├── InstallProgress.ts
│ ├── InstallState.ts
│ ├── InstallType.ts
│ ├── NorthstarLaunchOptions.ts
│ ├── NorthstarMod.ts
│ ├── NorthstarThunderstoreRelease.ts
│ ├── NorthstarThunderstoreReleaseWrapper.ts
│ ├── Project.ts
│ ├── PullRequestType.ts
│ ├── PullsApiResponseElement.ts
│ ├── ReleaseInfo.ts
│ ├── Repo.ts
│ ├── Tag.ts
│ ├── TagWrapper.ts
│ ├── ThunderstoreMod.ts
│ └── ThunderstoreModVersion.ts
├── build.rs
├── capabilities
│ ├── default.json
│ └── desktop.json
├── icons
│ ├── 128x128.png
│ ├── 128x128@2x.png
│ ├── 32x32.png
│ ├── Square107x107Logo.png
│ ├── Square142x142Logo.png
│ ├── Square150x150Logo.png
│ ├── Square284x284Logo.png
│ ├── Square30x30Logo.png
│ ├── Square310x310Logo.png
│ ├── Square44x44Logo.png
│ ├── Square71x71Logo.png
│ ├── Square89x89Logo.png
│ ├── StoreLogo.png
│ ├── icon.icns
│ ├── icon.ico
│ └── icon.png
├── src
│ ├── constants.rs
│ ├── development
│ │ └── mod.rs
│ ├── github
│ │ ├── mod.rs
│ │ ├── pull_requests.rs
│ │ └── release_notes.rs
│ ├── lib.rs
│ ├── main.rs
│ ├── mod_management
│ │ ├── legacy.rs
│ │ ├── mod.rs
│ │ └── plugins.rs
│ ├── northstar
│ │ ├── install.rs
│ │ ├── mod.rs
│ │ └── profile.rs
│ ├── platform_specific
│ │ ├── linux.rs
│ │ ├── mod.rs
│ │ └── windows.rs
│ ├── repair_and_verify
│ │ └── mod.rs
│ ├── thunderstore
│ │ └── mod.rs
│ └── util.rs
└── tauri.conf.json
└── src-vue
├── .gitignore
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
├── App.vue
├── assets
│ ├── 1009235.jpg
│ ├── mp_colony020033.jpg
│ ├── thunderstore-icon.png
│ └── wallpaperflare.com_wallpaper.jpg
├── components
│ ├── InstallProgressBar.vue
│ ├── LanguageSelector.vue
│ ├── LocalModCard.vue
│ ├── ModsMenu.vue
│ ├── NotificationButton.vue
│ ├── PlayButton.vue
│ ├── PullRequestsSelector.vue
│ └── ThunderstoreModCard.vue
├── i18n
│ └── lang
│ │ ├── da.json
│ │ ├── de.json
│ │ ├── en.json
│ │ ├── es.json
│ │ ├── fr.json
│ │ ├── it.json
│ │ ├── pl.json
│ │ ├── ru.json
│ │ └── zh_Hans.json
├── main.ts
├── plugins
│ ├── modules
│ │ ├── notifications.ts
│ │ ├── pull_requests.ts
│ │ └── search.ts
│ └── store.ts
├── style.css
├── utils
│ ├── GameInstall.ts
│ ├── NorthstarState.ts
│ ├── ReleaseCanal.ts
│ ├── SortOptions.d.ts
│ ├── Tabs.ts
│ ├── filter.ts
│ ├── thunderstore
│ │ ├── ThunderstoreModStatus.ts
│ │ └── version.ts
│ └── ui.ts
├── views
│ ├── ChangelogView.vue
│ ├── DeveloperView.vue
│ ├── ModsView.vue
│ ├── PlayView.vue
│ ├── RepairView.vue
│ ├── SettingsView.vue
│ └── mods
│ │ ├── LocalModsView.vue
│ │ └── ThunderstoreModsView.vue
├── vite-env.d.ts
└── vuex-shim.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
/.editorconfig:
--------------------------------------------------------------------------------
1 | # For more info on `.editorconfig` file see https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*.{rs,ts,vue,css}]
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 4
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Configures dependabot
2 |
3 | version: 2
4 | updates:
5 | # Root NPM package
6 | - package-ecosystem: 'npm'
7 | directory: '/'
8 | schedule:
9 | interval: "monthly"
10 | commit-message:
11 | prefix: "chore: "
12 |
13 | # NPM packages
14 | - package-ecosystem: 'npm'
15 | directory: '/src-vue'
16 | schedule:
17 | interval: "monthly"
18 | commit-message:
19 | prefix: "chore: "
20 |
21 | # Rust crates
22 | - package-ecosystem: 'cargo'
23 | directory: '/src-tauri'
24 | schedule:
25 | interval: "monthly"
26 | commit-message:
27 | prefix: "chore: "
28 |
--------------------------------------------------------------------------------
/.github/workflows/merge-conflict-auto-label.yml:
--------------------------------------------------------------------------------
1 | name: Merge Conflict Auto Label
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | jobs:
8 | triage:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: mschilde/auto-label-merge-conflicts@master
12 | with:
13 | CONFLICT_LABEL_NAME: "merge conflicts"
14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 | MAX_RETRIES: 5
16 | WAIT_MS: 5000
17 |
--------------------------------------------------------------------------------
/.github/workflows/push-test.yml:
--------------------------------------------------------------------------------
1 | name: "test-on-push"
2 | on:
3 | push:
4 | pull_request:
5 | schedule:
6 | - cron: "0 0 * * 0" # Run weekly to cover rust toolchain updates
7 |
8 | jobs:
9 | # Ensure version numbers in various places match up
10 | ensure-same-version:
11 | runs-on: ubuntu-22.04
12 | steps:
13 | - uses: actions/checkout@v4
14 | - name: install dependencies
15 | run: |
16 | pip install toml
17 | - name: Run check
18 | run: |
19 | python3 scripts/check_version_numbers.py
20 |
21 | # Ensure correct Rust code formatting
22 | formatting:
23 | name: format-check
24 | runs-on: ubuntu-latest
25 | steps:
26 | - uses: actions/checkout@v4
27 | - uses: dtolnay/rust-toolchain@stable
28 | with:
29 | toolchain: stable
30 | components: rustfmt
31 | - name: Format check
32 | run: cargo fmt --manifest-path src-tauri/Cargo.toml --all -- --check
33 |
34 | clippy:
35 | strategy:
36 | fail-fast: false
37 | matrix:
38 | platform: [ubuntu-22.04, windows-latest]
39 |
40 | name: clippy-check
41 | runs-on: ${{ matrix.platform }}
42 | steps:
43 | - uses: actions/checkout@v4
44 | - uses: dtolnay/rust-toolchain@stable
45 | with:
46 | toolchain: stable
47 | components: clippy
48 | - name: install dependencies (ubuntu only)
49 | if: matrix.platform == 'ubuntu-22.04'
50 | run: |
51 | sudo apt-get update
52 | sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
53 | - name: Create dist folder (Ubuntu only)
54 | if: matrix.platform == 'ubuntu-22.04'
55 | run: mkdir --parent src-vue/dist
56 | - name: Create dist folder (Windows only)
57 | if: matrix.platform == 'windows-latest'
58 | run: New-Item -ItemType Directory -Force -Path "src-vue\dist"
59 | - name: Run clippy
60 | run: cargo clippy --manifest-path src-tauri/Cargo.toml -- --no-deps --deny warnings
61 |
62 | # Ensure committed bindings correct
63 | autogen-ts-bindings-check:
64 | runs-on: ubuntu-22.04
65 | steps:
66 | - uses: actions/checkout@v4
67 | - uses: dtolnay/rust-toolchain@stable
68 | with:
69 | toolchain: stable
70 | - name: install dependencies (ubuntu only)
71 | run: |
72 | sudo apt-get update
73 | sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
74 |
75 | - name: Move original TypeScript bindings
76 | run: |
77 | cp -r src-tauri/bindings original-bindings
78 | rm -r src-tauri/bindings
79 |
80 | - name: Create empty dist folder # Otherwise tests fail
81 | run: mkdir src-vue/dist
82 |
83 | - name: Run Tests
84 | run: cargo test --manifest-path src-tauri/Cargo.toml
85 |
86 | - name: Compare TypeScript Bindings
87 | run: |
88 | diff -r src-tauri/bindings original-bindings
89 | if [[ $? -ne 0 ]]; then
90 | echo "Generated bindings are different from committed bindings"
91 | exit 1
92 | fi
93 |
94 | test-tauri:
95 | needs: ensure-same-version
96 | strategy:
97 | fail-fast: false
98 | matrix:
99 | platform: [ubuntu-22.04, windows-latest]
100 |
101 | runs-on: ${{ matrix.platform }}
102 | steps:
103 | - uses: actions/checkout@v4
104 | - name: setup node
105 | uses: actions/setup-node@v4
106 | with:
107 | node-version: 18
108 | - uses: dtolnay/rust-toolchain@stable
109 | with:
110 | toolchain: stable
111 | - name: install dependencies (ubuntu only)
112 | if: matrix.platform == 'ubuntu-22.04'
113 | run: |
114 | sudo apt-get update
115 | sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
116 | - name: Disable self-updater
117 | shell: bash
118 | run: |
119 | jq 'del(.plugins.updater)' src-tauri/tauri.conf.json | jq 'del(.bundle.createUpdaterArtifacts)' > src-tauri/tauri.conf.json.new
120 | rm src-tauri/tauri.conf.json
121 | mv src-tauri/tauri.conf.json.new src-tauri/tauri.conf.json
122 | - uses: Swatinem/rust-cache@v2 # Cache Rust build artifacts
123 | with:
124 | workspaces: |
125 | src-tauri
126 | - name: install app dependencies and build it
127 | env:
128 | TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
129 | run: |
130 | npm clean-install
131 | cd src-vue && npm clean-install && cd ..
132 | npm run tauri build
133 | - uses: tauri-apps/tauri-action@v0
134 | env:
135 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
136 | TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
137 | - name: Upload Linux artifact
138 | if: matrix.platform == 'ubuntu-22.04'
139 | uses: actions/upload-artifact@v4
140 | with:
141 | name: linux-artifacts
142 | path: |
143 | src-tauri/target/release/bundle/appimage/*
144 | - name: Upload Linux AppImage
145 | if: matrix.platform == 'ubuntu-22.04'
146 | uses: actions/upload-artifact@v4
147 | with:
148 | name: linux-appimage
149 | path: |
150 | src-tauri/target/release/bundle/appimage/*.AppImage
151 | - name: Upload Windows artifact
152 | if: matrix.platform == 'windows-latest'
153 | uses: actions/upload-artifact@v4
154 | with:
155 | name: windows-artifacts
156 | path: |
157 | src-tauri/target/release/bundle/msi/*
158 | src-tauri/target/release/app.pdb
159 | - name: Additionally upload Windows installer separately
160 | if: matrix.platform == 'windows-latest'
161 | uses: actions/upload-artifact@v4
162 | with:
163 | name: windows-msi
164 | path: |
165 | src-tauri/target/release/bundle/msi/*.msi
166 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: "release"
2 | on:
3 | push:
4 | tags:
5 | - 'v*'
6 |
7 | permissions:
8 | contents: write # Needed to write to GitHub draft release
9 |
10 | jobs:
11 | # Ensure version numbers in various places match up
12 | ensure-same-version:
13 | runs-on: ubuntu-22.04
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: install dependencies
17 | run: |
18 | pip install toml
19 | - name: Run check
20 | run: |
21 | python3 scripts/check_version_numbers.py --release ${{github.ref_name}}
22 |
23 | build:
24 | needs: ensure-same-version
25 | strategy:
26 | fail-fast: false
27 | matrix:
28 | platform: [ubuntu-22.04, windows-latest]
29 |
30 | runs-on: ${{ matrix.platform }}
31 | steps:
32 | - uses: actions/checkout@v4
33 | - name: setup node
34 | uses: actions/setup-node@v4
35 | with:
36 | node-version: 18
37 | - name: install Rust stable
38 | uses: dtolnay/rust-toolchain@stable
39 | with:
40 | toolchain: stable
41 | - name: install dependencies (ubuntu only)
42 | if: matrix.platform == 'ubuntu-22.04'
43 | run: |
44 | sudo apt-get update
45 | sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
46 | - uses: Swatinem/rust-cache@v2 # Cache Rust build artifacts
47 | with:
48 | workspaces: |
49 | src-tauri
50 | - name: install app dependencies and build it
51 | env:
52 | TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
53 | run: |
54 | npm clean-install
55 | cd src-vue && npm clean-install && cd ..
56 | npm run tauri build
57 | - uses: tauri-apps/tauri-action@v0
58 | env:
59 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60 | TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
61 | - name: upload build artifact (windows)
62 | if: matrix.platform == 'windows-latest'
63 | uses: actions/upload-artifact@v4
64 | with:
65 | name: windows-artifacts
66 | path: |
67 | src-tauri/target/release/bundle/msi/*msi*
68 | src-tauri/target/release/flightcore.pdb
69 | - name: upload build artifact (linux)
70 | if: matrix.platform == 'ubuntu-22.04'
71 | uses: actions/upload-artifact@v4
72 | with:
73 | name: linux-artifacts
74 | path: |
75 | src-tauri/target/release/bundle/appimage/*AppImage*
76 | - name: Install sentry-cli (Windows only)
77 | if: matrix.platform == 'windows-latest'
78 | run: |
79 | curl --location --output sentry-cli.exe "https://release-registry.services.sentry.io/apps/sentry-cli/latest?response=download&arch=x86_64&platform=Windows&package=sentry-cli"
80 | - name: Run sentry-cli to upload pdb (Windows only)
81 | if: matrix.platform == 'windows-latest'
82 | env:
83 | SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
84 | SENTRY_ORG: northstar-kv
85 | SENTRY_PROJECT: flightcore
86 | run: |
87 | ./sentry-cli.exe upload-dif --wait src-tauri/target/release/flightcore.pdb
88 | - name: Release
89 | uses: softprops/action-gh-release@v1
90 | with:
91 | draft: true
92 | files: |
93 | src-tauri/target/release/bundle/appimage/*AppImage*
94 | src-tauri/target/release/bundle/msi/*msi*
95 |
96 | create-release-file:
97 | needs: build
98 | runs-on: ubuntu-22.04
99 | steps:
100 | - uses: actions/checkout@v4
101 | - uses: actions/download-artifact@v4
102 | - name: Create release file
103 | run: |
104 | ls -al
105 | ls -al linux-artifacts/
106 | ls -al windows-artifacts/
107 | ls -al windows-artifacts/bundle/
108 | ls -al windows-artifacts/bundle/msi/
109 | python3 scripts/create-release-file.py --version ${{github.ref_name}}
110 |
111 | - name: upload release file
112 | uses: softprops/action-gh-release@v1
113 | with:
114 | draft: true
115 | files: |
116 | latest-release.json
117 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node modules
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "tauri-apps.tauri-vscode",
4 | "rust-lang.rust-analyzer",
5 | "vue.volar"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "tauri dev",
8 | "type": "shell",
9 | "command": "npm",
10 | "args": [
11 | "run",
12 | "tauri",
13 | "dev"
14 | ],
15 | "group": {
16 | "kind": "build",
17 | "isDefault": true
18 | }
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 R2NorthstarTools
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | # FlightCore
10 |
11 | A [Northstar](https://northstar.tf/) installer, updater, and mod-manager
12 |
13 | 
14 |
15 | ## Install
16 |
17 | Downloads are available on the [releases page](https://github.com/R2NorthstarTools/FlightCore/releases).
18 |
19 | **Windows:** Download `FlightCore_X.Y.Z_x64_en-US.msi` and then run the installer by double-clicking the file.
20 |
21 | **Linux:** Download `flight-core_X.Y.Z_amd64.AppImage`, put it in a preferred location and make it executable. A Flatpak version is planned for the future.
22 |
23 | All versions of FlightCore feature an auto-updater that will ask to self-update on new releases.
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Frequently Asked Questions (FAQ)
32 |
33 | Answers to frequently asked questions can be found in [docs/FAQ.md](docs/FAQ.md)
34 |
35 | ## Development
36 |
37 | If you'd like to contribute to FlightCore, see [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
38 |
39 | If you are a Northstar developer/contributor, you might want to look at [docs/DEV-TOOLS.md](docs/DEV-TOOLS.md)
40 |
41 | ### Translating
42 |
43 | Translations can be submitted via [weblate](https://translate.harmony.tf/projects/northstar/flightcore/). \
44 | If you want to add translations for a new language that does not exist in FlightCore yet, please [reach out via GitHub issues](https://github.com/R2NorthstarTools/FlightCore/issues/new) so that we can add support for it.
45 |
46 |
47 |
48 |
49 |
50 | ## Roadmap
51 |
52 | --> See https://github.com/R2NorthstarTools/FlightCore/issues/1
53 |
--------------------------------------------------------------------------------
/docs/DEV-TOOLS.md:
--------------------------------------------------------------------------------
1 | # Dev tools
2 |
3 | 
4 |
5 | FlightCore features a hidden view that contains development features.
6 |
7 | It's targetted at both Northstar and FlightCore contributors. Among other things it contains buttons for unreleased features in FlightCore and tools to help with Northstar development.
8 |
9 | To activate it, spam click the FlightCore version number in the settings view at least 6 times. After that a new entry named _DEV_ should appear in the menubar.
10 |
11 | ## Northstar
12 |
13 | ### Pull request install
14 |
15 | The dev view offers a way to install pull request from the [NorthstarLauncher](https://github.com/R2Northstar/NorthstarLauncher) and [NorthstarMods](https://github.com/R2Northstar/NorthstarMods) repositories.
16 |
17 | Launcher pull requests overwrite `NorthstarLauncher.exe` and `Northstar.dll`.
18 |
19 | Mod pull requests install into a separate profile called `R2Northstar-PR-test-managed-folder`. \
20 | When installing a mods PR, FlightCore will place `r2ns-launch-mod-pr-version.bat` into your Titanfall2 directory that can be used to run that PR profile directly. \
21 | The batch file simply runs `NorthstarLauncher.exe -profile=R2Northstar-PR-test-managed-folder`
22 |
23 |
24 | ## FlightCore
25 |
26 | The dev view contains various buttons that call functions that might not be fully implemented or tested yet.
27 |
28 | Additionally it has some buttons for testing like the _Panic button_ which force crashes the application to test automatic log uploading on crash among other things.
29 |
--------------------------------------------------------------------------------
/docs/FAQ.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | ## What is FlightCore?
4 |
5 | FlightCore is a Northstar installer, updater, and mod-manager for Northstar?
6 |
7 | You can use it to easily install and update Northstar as well as for installing, updating, and managing mods for Northstar.
8 |
9 | ## What is Northstar?
10 |
11 | Northstar is a modding and custom server framework for Titanfall2.
12 |
13 | You use it to do stuff like
14 |
15 | - [this](https://www.youtube.com/watch?v=en06Y6CPMQg)
16 | - [or this](https://www.youtube.com/watch?v=suhBGqzDbNA)
17 | - [or this](https://www.youtube.com/watch?v=vyUxAwobY60)
18 |
19 | ## I have an issue with FlightCore, where do I go?
20 |
21 | Check [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
22 |
23 | ## Why yet another Northstar intaller/updater/mod-manager instead of contributing to an existing one?
24 |
25 | The 3 main GUI tools for handling such tasks with Norhtstar are
26 |
27 | - [r2modman](https://github.com/ebkr/r2modmanPlus)
28 | - [Viper](https://github.com/0neGal/viper)
29 | - [VTOL](https://github.com/BigSpice/VTOL)
30 |
31 | while they get most of the work done, each of them has their own problem.
32 |
33 | - **r2modman** has not too great UX and given that it also has to support other games there's not a(n easy) way to quickly add new features specific to Northstar
34 | - **Viper** probably has the best UX but is missing features such as Origin process runtime detection (to avoid LSX errors) and lacks the ability to install Northstar from Thunderstore.
35 | - **VTOL** has recently undergone a rewrite that removes a lot of older issues (such as requiring to be run as admin), however it is Windows exclusive and requires installing an additional library not shipped directly with the application, confusing some users. It also has a lot of edge case handling that while giving a smoother user experience blows up code base complexity.
36 |
37 | With that said, FlightCore is not written from scratch. For handling Northstar specific logic, functions are re-used from the CLI-only Northstar installer called [papa](https://github.com/AnActualEmerald/papa) by making use of the underlying library [libthermite](https://crates.io/crates/libthermite).
38 |
39 | The plan is to upstream any changes to `libthermite` so that it can be re-used by any other Rust-based Northstar installer.
40 |
41 | ## I'd like to contribute to FlightCore, where do I start?
42 |
43 | Check [DEVELOPMENT.md](DEVELOPMENT.md)
44 |
--------------------------------------------------------------------------------
/docs/TROUBLESHOOTING.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | Got an issue with FlightCore? Hopefully one of the steps below will help you resolve it. If not open an [issue on GitHub](https://github.com/R2NorthstarTools/FlightCore/issues/new) or ping `@geckoeidechse` on the Northstar Discord.
4 |
5 | ## FlightCore won't launch
6 |
7 | If you are on Windows and FlightCore won't start but instead shows an error message like this
8 |
9 | 
10 |
11 | that means that WebView2 is not installed. WebView2 is an embedded browser framework used by FlightCore to display its GUI.
12 |
13 | To install it, you can grab the latest version from the Microsoft website: \
14 | https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section
15 |
16 | 
17 |
18 | (make sure to select _Evergreen Bootstrapper_ -> _Download_).
19 |
20 |
21 | ## Linux
22 |
23 | ### FlightCore launches, but the main window is blank
24 | This may be caused by tauri-apps/tauri#5143
25 |
26 | Try setting this environment variable when starting FlightCore:
27 | `WEBKIT_DISABLE_COMPOSITING_MODE=1`
28 |
29 | ```bash
30 | WEBKIT_DISABLE_COMPOSITING_MODE=1 ./flight-core.AppImage
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/assets/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/Square310x310Logo.png
--------------------------------------------------------------------------------
/docs/assets/dev-view-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/dev-view-screenshot.png
--------------------------------------------------------------------------------
/docs/assets/downloadbutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/downloadbutton.png
--------------------------------------------------------------------------------
/docs/assets/flightcore-webview2-windows-error-message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/flightcore-webview2-windows-error-message.png
--------------------------------------------------------------------------------
/docs/assets/main-window-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/main-window-screenshot.png
--------------------------------------------------------------------------------
/docs/assets/webview2-download-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/docs/assets/webview2-download-screenshot.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
65 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flightcore",
3 | "scripts": {
4 | "tauri": "tauri"
5 | },
6 | "dependencies": {
7 | "@tauri-apps/api": "^2",
8 | "@tauri-apps/plugin-opener": "^2"
9 | },
10 | "devDependencies": {
11 | "@tauri-apps/cli": "^2"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/scripts/check_version_numbers.py:
--------------------------------------------------------------------------------
1 | # %%
2 | """"Ensure that version numbers between `tauri.conf.json`, `cargo.toml`, and GitHub release are the same"""
3 | import json
4 | import toml
5 | import sys
6 |
7 | with open("src-tauri/tauri.conf.json", "rt") as f:
8 | tauri_conf_json = json.load(f)
9 |
10 | with open("src-tauri/Cargo.toml", "rt") as f:
11 | Cargo_toml = toml.load(f)
12 |
13 | tauri_conf_json_version = tauri_conf_json["version"]
14 | Cargo_toml_version = Cargo_toml["package"]["version"]
15 |
16 | # Ensure same
17 | assert(tauri_conf_json_version == Cargo_toml_version)
18 |
19 | # Check release tag additionally if release
20 | if "--release" in sys.argv:
21 | print("TODO")
22 | release_tag = sys.argv[2]
23 | print(release_tag)
24 | assert(release_tag == f"v{tauri_conf_json_version}")
25 |
--------------------------------------------------------------------------------
/scripts/create-release-file.py:
--------------------------------------------------------------------------------
1 | # %%
2 | import json
3 | import datetime
4 | import sys
5 |
6 | assert("--version" in sys.argv)
7 |
8 | version_number = sys.argv[2]
9 | version_number_stripped_v = version_number.replace("v", "")
10 |
11 | PATH_TO_LINUX_SIG = f"./linux-artifacts/FlightCore_{version_number_stripped_v}_amd64.AppImage.tar.gz.sig"
12 | PATH_TO_WINDOWS_SIG = f"./windows-artifacts/bundle/msi/FlightCore_{version_number_stripped_v}_x64_en-US.msi.zip.sig"
13 |
14 | # Text to show in update notification
15 | RELEASE_TEXT = "See the following link for release notes: https://github.com/R2NorthstarTools/FlightCore/releases"
16 |
17 | # Read signatures
18 | with open(PATH_TO_LINUX_SIG, "rt") as f:
19 | linux_sig = f.read()
20 | with open(PATH_TO_WINDOWS_SIG, "rt") as f:
21 | windows_sig = f.read()
22 |
23 |
24 | current_datetime_string = str(datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z")
25 |
26 | release_dict = {
27 | "version": f"{version_number}",
28 | "notes": f"{RELEASE_TEXT}",
29 | "pub_date": current_datetime_string,
30 | "platforms": {
31 | "linux-x86_64": {
32 | "signature": linux_sig,
33 | "url": f"https://github.com/R2NorthstarTools/FlightCore/releases/download/{version_number}/flight-core_{version_number_stripped_v}_amd64.AppImage.tar.gz"
34 | },
35 | "windows-x86_64": {
36 | "signature": windows_sig,
37 | "url": f"https://github.com/R2NorthstarTools/FlightCore/releases/download/{version_number}/FlightCore_{version_number_stripped_v}_x64_en-US.msi.zip"
38 | }
39 | }
40 | }
41 | json_string = json.dumps(release_dict, indent=4)
42 | print(json_string)
43 | # %%
44 | RESULT_JSON_FILENAME = "latest-release.json"
45 | with open(RESULT_JSON_FILENAME, "wt") as f:
46 | f.write(json_string)
47 | # %%
48 |
--------------------------------------------------------------------------------
/src-tauri/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | /target/
4 |
5 | # Generated by Tauri
6 | # will have schema files for capabilities auto-completion
7 | /gen/schemas
8 |
--------------------------------------------------------------------------------
/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "flightcore"
3 | version = "3.0.6"
4 | description = "Mod-manager for Northstar"
5 | authors = ["https://github.com/R2NorthstarTools/FlightCore/graphs/contributors"]
6 | license = "MIT"
7 | repository = "https://github.com/R2NorthstarTools/FlightCore"
8 | edition = "2021"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [profile.release]
13 | # Keeps line tables in built binary
14 | # c.f.: https://doc.rust-lang.org/cargo/reference/profiles.html#debug
15 | # This is done to see line numbers in stack trace on sentry.io
16 | debug = 1
17 |
18 | [lib]
19 | # The `_lib` suffix may seem redundant but it is necessary
20 | # to make the lib name unique and wouldn't conflict with the bin name.
21 | # This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
22 | name = "tauri_app_lib"
23 | crate-type = ["staticlib", "cdylib", "rlib"]
24 |
25 | [build-dependencies]
26 | tauri-build = { version = "2", features = [] }
27 |
28 | [dependencies]
29 | serde_json = "1.0"
30 | serde = { version = "1.0", features = ["derive"] }
31 | tauri = { version = "2", features = [] }
32 | tauri-plugin-dialog = "2"
33 | tauri-plugin-opener = "2"
34 | tauri-plugin-store = "2"
35 | tokio = { version = "1", features = ["full"] }
36 | # Sentry (crash) logging
37 | sentry = "0.32"
38 | sentry-log = "0.34"
39 | # Find steam games
40 | steamlocate = "2.0.0-beta.2"
41 | # Error messages
42 | anyhow = "1.0"
43 | # libthermite for Northstar/mod install handling
44 | libthermite = { version = "0.8.1", features = ["proton"] }
45 | # zip stuff
46 | zip = "0.6.2"
47 | # Regex
48 | regex = "1.10"
49 | # Read out running application process names
50 | sysinfo = "0.30.13"
51 | # HTTP requests
52 | reqwest = { version = "0.11", features = ["blocking", "json"] }
53 | # JSON5 parsing support (allows comments in JSON)
54 | json5 = "0.4.1"
55 | # Async recursion for recursive mod install
56 | async-recursion = "1.1.1"
57 | # For parsing timestamps
58 | chrono = "0.4.38"
59 | # TypeScript bindings
60 | ts-rs = "10.0"
61 | # const formatting
62 | const_format = "0.2.33"
63 | # Logging libraries
64 | pretty_env_logger = "0.5.0"
65 | log = "0.4"
66 | # Extracting zip files easily
67 | zip-extract = "0.1.3"
68 | # open urls
69 | open = "5.3.0"
70 | semver = "1.0"
71 | # simplified filesystem access
72 | glob = "0.3.1"
73 | dirs = "5"
74 | # Random number stuff
75 | rand = "0.8.5"
76 |
77 | # Interacting with GitHub
78 | octocrab = "0.38.0"
79 | # Library for removing markdown links
80 | remove-markdown-links = "1.0.0"
81 |
82 |
83 | [target.'cfg(windows)'.dependencies]
84 | # Windows API stuff
85 | winapi = "0.3.9"
86 | winreg = "0.52.0"
87 |
88 | [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
89 | tauri-plugin-updater = "2"
90 |
--------------------------------------------------------------------------------
/src-tauri/bindings/CommitHead.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { Repo } from "./Repo";
3 |
4 | export type CommitHead = { sha: string, ref: string, repo: Repo, };
5 |
--------------------------------------------------------------------------------
/src-tauri/bindings/FlightCoreVersion.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type FlightCoreVersion = { tag_name: string, published_at: string, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/InstallProgress.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { InstallState } from "./InstallState";
3 |
4 | export type InstallProgress = { current_downloaded: bigint, total_size: bigint, state: InstallState, };
5 |
--------------------------------------------------------------------------------
/src-tauri/bindings/InstallState.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type InstallState = "Downloading" | "Extracting" | "Done";
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/InstallType.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | /**
4 | * Defines how Titanfall2 was installed (Steam, Origin, ...)
5 | */
6 | export type InstallType = "STEAM" | "ORIGIN" | "EAPLAY" | "UNKNOWN";
7 |
--------------------------------------------------------------------------------
/src-tauri/bindings/NorthstarLaunchOptions.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type NorthstarLaunchOptions = { launch_via_steam: boolean, bypass_checks: boolean, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/NorthstarMod.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | /**
4 | * Object holding various information about a Northstar mod
5 | */
6 | export type NorthstarMod = { name: string, version: string | null, thunderstore_mod_string: string | null, enabled: boolean, directory: string, };
7 |
--------------------------------------------------------------------------------
/src-tauri/bindings/NorthstarThunderstoreRelease.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type NorthstarThunderstoreRelease = { package: string, version: string, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/NorthstarThunderstoreReleaseWrapper.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { NorthstarThunderstoreRelease } from "./NorthstarThunderstoreRelease";
3 |
4 | export type NorthstarThunderstoreReleaseWrapper = { label: string, value: NorthstarThunderstoreRelease, };
5 |
--------------------------------------------------------------------------------
/src-tauri/bindings/Project.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type Project = "FlightCore" | "Northstar";
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/PullRequestType.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type PullRequestType = "Mods" | "Launcher";
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/PullsApiResponseElement.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { CommitHead } from "./CommitHead";
3 |
4 | export type PullsApiResponseElement = { number: bigint, title: string, url: string, head: CommitHead, html_url: string, labels: Array, };
5 |
--------------------------------------------------------------------------------
/src-tauri/bindings/ReleaseInfo.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type ReleaseInfo = { name: string, published_at: string, body: string, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/Repo.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type Repo = { full_name: string, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/Tag.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type Tag = { name: string, };
4 |
--------------------------------------------------------------------------------
/src-tauri/bindings/TagWrapper.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { Tag } from "./Tag";
3 |
4 | /**
5 | * Wrapper type needed for frontend
6 | */
7 | export type TagWrapper = { label: string, value: Tag, };
8 |
--------------------------------------------------------------------------------
/src-tauri/bindings/ThunderstoreMod.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 | import type { ThunderstoreModVersion } from "./ThunderstoreModVersion";
3 |
4 | export type ThunderstoreMod = { name: string, full_name: string, owner: string, package_url: string, date_created: string, date_updated: string, uuid4: string, rating_score: number, is_pinned: boolean, is_deprecated: boolean, has_nsfw_content: boolean, categories: Array, versions: Array, };
5 |
--------------------------------------------------------------------------------
/src-tauri/bindings/ThunderstoreModVersion.ts:
--------------------------------------------------------------------------------
1 | // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2 |
3 | export type ThunderstoreModVersion = { name: string, full_name: string, description: string, icon: string, version_number: string, dependencies: Array, download_url: string, downloads: number, date_created: string, website_url: string, is_active: boolean, uuid4: string, file_size: bigint, };
4 |
--------------------------------------------------------------------------------
/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/src-tauri/capabilities/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../gen/schemas/desktop-schema.json",
3 | "identifier": "default",
4 | "description": "Capability for the main window",
5 | "windows": [
6 | "main",
7 | "RepairWindow"
8 | ],
9 | "permissions": [
10 | "core:window:allow-minimize",
11 | "core:window:allow-request-user-attention",
12 | "core:window:allow-start-dragging",
13 | "core:default",
14 | "opener:default",
15 | "store:default",
16 | "updater:default"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src-tauri/capabilities/desktop.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "desktop-capability",
3 | "platforms": [
4 | "macOS",
5 | "windows",
6 | "linux"
7 | ],
8 | "windows": [
9 | "main"
10 | ],
11 | "permissions": [
12 | "updater:default"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/src-tauri/src/constants.rs:
--------------------------------------------------------------------------------
1 | // This file stores various global constants values
2 | use const_format::concatcp;
3 | use std::time::Duration;
4 |
5 | /// FlightCore user agent for web requests
6 | pub const APP_USER_AGENT: &str = concatcp!("FlightCore/", env!("CARGO_PKG_VERSION"));
7 |
8 | /// URL of the Northstar masterserver
9 | pub const MASTER_SERVER_URL: &str = "https://northstar.tf";
10 |
11 | /// server list endpoint
12 | pub const SERVER_BROWSER_ENDPOINT: &str = "/client/servers";
13 |
14 | /// List of core Northstar mods
15 | pub const CORE_MODS: [&str; 3] = [
16 | "Northstar.Client",
17 | "Northstar.Custom",
18 | "Northstar.CustomServers",
19 | ];
20 |
21 | /// List of Thunderstoremods that shouldn't be installable
22 | /// as they behave different than common Squirrel mods
23 | pub const BLACKLISTED_MODS: [&str; 3] = [
24 | "northstar-Northstar",
25 | "northstar-NorthstarReleaseCandidate",
26 | "ebkr-r2modman",
27 | ];
28 |
29 | /// List of Thunderstoremods that have some specific install requirements that makes them different from standard mods
30 | pub const MODS_WITH_SPECIAL_REQUIREMENTS: [&str; 2] =
31 | ["NanohmProtogen-VanillaPlus", "NachosChipeados-VanillaPlus"];
32 |
33 | /// Order in which the sections for release notes should be displayed
34 | pub const SECTION_ORDER: [&str; 11] = [
35 | "feat", "fix", "docs", "style", "refactor", "build", "test", "i18n", "ci", "chore", "other",
36 | ];
37 |
38 | /// Statistics (players and servers counts) refresh delay
39 | pub const REFRESH_DELAY: Duration = Duration::from_secs(5 * 60);
40 |
41 | /// Flightcore repo name and org name on GitHub
42 | pub const FLIGHTCORE_REPO_NAME: &str = "R2NorthstarTools/FlightCore";
43 |
44 | /// Northstar release repo name and org name on GitHub
45 | pub const NORTHSTAR_RELEASE_REPO_NAME: &str = "R2Northstar/Northstar";
46 |
47 | /// NorthstarLauncher repo name on GitHub
48 | pub const NORTHSTAR_LAUNCHER_REPO_NAME: &str = "NorthstarLauncher";
49 |
50 | /// NorthstarMods repo name on GitHub
51 | pub const NORTHSTAR_MODS_REPO_NAME: &str = "NorthstarMods";
52 |
53 | /// URL to launcher commits API URL
54 | pub const NS_LAUNCHER_COMMITS_API_URL: &str =
55 | "https://api.github.com/repos/R2Northstar/NorthstarLauncher/commits";
56 |
57 | /// Filename of DLL that Northstar uses
58 | pub const NORTHSTAR_DLL: &str = "Northstar.dll";
59 |
60 | /// Profile that Northstar defaults to and ships with
61 | pub const NORTHSTAR_DEFAULT_PROFILE: &str = "R2Northstar";
62 |
--------------------------------------------------------------------------------
/src-tauri/src/development/mod.rs:
--------------------------------------------------------------------------------
1 | use crate::constants::NS_LAUNCHER_COMMITS_API_URL;
2 | use crate::github::{
3 | pull_requests::{check_github_api, download_zip_into_memory, get_launcher_download_link},
4 | CommitInfo,
5 | };
6 |
7 | #[tauri::command]
8 | pub async fn install_git_main(game_install_path: &str) -> Result {
9 | // Get list of commits
10 | let commits: Vec = serde_json::from_value(
11 | check_github_api(NS_LAUNCHER_COMMITS_API_URL)
12 | .await
13 | .expect("Failed request"),
14 | )
15 | .unwrap();
16 |
17 | // Get latest commit...
18 | let latest_commit_sha = commits[0].sha.clone();
19 | // ...and according artifact download URL
20 | let download_url = get_launcher_download_link(latest_commit_sha.clone()).await?;
21 |
22 | let archive = match download_zip_into_memory(download_url).await {
23 | Ok(archive) => archive,
24 | Err(err) => return Err(err.to_string()),
25 | };
26 |
27 | let extract_directory = format!(
28 | "{}/___flightcore-temp/download-dir/launcher-pr-{}",
29 | game_install_path, latest_commit_sha
30 | );
31 | match std::fs::create_dir_all(extract_directory.clone()) {
32 | Ok(_) => (),
33 | Err(err) => {
34 | return Err(format!(
35 | "Failed creating temporary download directory: {}",
36 | err
37 | ))
38 | }
39 | };
40 |
41 | let target_dir = std::path::PathBuf::from(extract_directory.clone()); // Doesn't need to exist
42 | match zip_extract::extract(std::io::Cursor::new(archive), &target_dir, true) {
43 | Ok(()) => (),
44 | Err(err) => {
45 | return Err(format!("Failed unzip: {}", err));
46 | }
47 | };
48 |
49 | // Copy only necessary files from temp dir
50 | // Copy:
51 | // - NorthstarLauncher.exe
52 | // - Northstar.dll
53 | let files_to_copy = vec!["NorthstarLauncher.exe", "Northstar.dll"];
54 | for file_name in files_to_copy {
55 | let source_file_path = format!("{}/{}", extract_directory, file_name);
56 | let destination_file_path = format!("{}/{}", game_install_path, file_name);
57 | match std::fs::copy(source_file_path, destination_file_path) {
58 | Ok(_result) => (),
59 | Err(err) => {
60 | return Err(format!(
61 | "Failed to copy necessary file {} from temp dir: {}",
62 | file_name, err
63 | ))
64 | }
65 | };
66 | }
67 |
68 | // delete extract directory
69 | match std::fs::remove_dir_all(&extract_directory) {
70 | Ok(()) => (),
71 | Err(err) => {
72 | return Err(format!(
73 | "Failed to delete temporary download directory: {}",
74 | err
75 | ))
76 | }
77 | }
78 |
79 | log::info!(
80 | "All done with installing launcher from {}",
81 | latest_commit_sha
82 | );
83 | Ok(latest_commit_sha)
84 | }
85 |
--------------------------------------------------------------------------------
/src-tauri/src/github/release_notes.rs:
--------------------------------------------------------------------------------
1 | use rand::prelude::SliceRandom;
2 | use serde::{Deserialize, Serialize};
3 | use std::vec::Vec;
4 | use ts_rs::TS;
5 |
6 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
7 | #[ts(export)]
8 | pub struct ReleaseInfo {
9 | pub name: String,
10 | pub published_at: String,
11 | pub body: String,
12 | }
13 |
14 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
15 | #[ts(export)]
16 | pub struct FlightCoreVersion {
17 | tag_name: String,
18 | published_at: String,
19 | }
20 |
21 | /// Gets newest FlighCore version from GitHub
22 | #[tauri::command]
23 | pub async fn get_newest_flightcore_version() -> Result {
24 | // Get newest version number from GitHub API
25 | log::info!("Checking GitHub API");
26 | let octocrab = octocrab::instance();
27 | let page = octocrab
28 | .repos("R2NorthstarTools", "FlightCore")
29 | .releases()
30 | .list()
31 | // Optional Parameters
32 | .per_page(1)
33 | .page(1u32)
34 | // Send the request
35 | .send()
36 | .await
37 | .map_err(|err| err.to_string())?;
38 |
39 | // Get newest element
40 | let latest_release_item = &page.items[0];
41 |
42 | let flightcore_version = FlightCoreVersion {
43 | tag_name: latest_release_item.tag_name.clone(),
44 | published_at: latest_release_item.published_at.unwrap().to_rfc3339(),
45 | };
46 | log::info!("Done checking GitHub API");
47 |
48 | Ok(flightcore_version)
49 | }
50 |
51 | /// Checks if installed FlightCore version is up-to-date
52 | /// false -> FlightCore install is up-to-date
53 | /// true -> FlightCore install is outdated
54 | #[tauri::command]
55 | pub async fn check_is_flightcore_outdated() -> Result {
56 | let newest_flightcore_release = get_newest_flightcore_version().await?;
57 | // Parse version number excluding leading `v`
58 | let newest_version = semver::Version::parse(&newest_flightcore_release.tag_name[1..]).unwrap();
59 |
60 | // Get version of installed FlightCore
61 | let current_version = env!("CARGO_PKG_VERSION");
62 | let current_version = semver::Version::parse(current_version).unwrap();
63 |
64 | #[cfg(debug_assertions)]
65 | let is_outdated = current_version < newest_version;
66 | #[cfg(not(debug_assertions))]
67 | let is_outdated = current_version != newest_version;
68 |
69 | // If outdated, check how new the update is
70 | if is_outdated {
71 | // Time to wait (2h) h * m * s
72 | let threshold_seconds = 2 * 60 * 60;
73 |
74 | // Get current time
75 | let current_time = chrono::Utc::now();
76 |
77 | // Get latest release time from GitHub API response
78 | let result = chrono::DateTime::parse_from_rfc3339(&newest_flightcore_release.published_at)
79 | .unwrap()
80 | .with_timezone(&chrono::Utc);
81 |
82 | // Check if current time is outside of threshold
83 | let diff = current_time - result;
84 | if diff.num_seconds() < threshold_seconds {
85 | // User would be outdated but the newest release is recent
86 | // therefore we do not wanna show outdated warning.
87 | return Ok(false);
88 | }
89 | return Ok(true);
90 | }
91 |
92 | Ok(is_outdated)
93 | }
94 |
95 | #[tauri::command]
96 | pub async fn get_northstar_release_notes() -> Result, String> {
97 | let octocrab = octocrab::instance();
98 | let page = octocrab
99 | .repos("R2Northstar", "Northstar")
100 | .releases()
101 | .list()
102 | // Optional Parameters
103 | .per_page(25)
104 | .page(1u32)
105 | // Send the request
106 | .send()
107 | .await
108 | .map_err(|err| err.to_string())?;
109 |
110 | // TODO there's probably a way to automatically serialize into the struct but I don't know yet how to
111 | let mut release_info_vector: Vec = vec![];
112 | for item in page.items {
113 | let release_info = ReleaseInfo {
114 | name: item.name.ok_or(String::from("Release name not found"))?,
115 | published_at: item
116 | .published_at
117 | .ok_or(String::from("Release date not found"))?
118 | .to_rfc3339(),
119 | body: item.body.ok_or(String::from("Release body not found"))?,
120 | };
121 | release_info_vector.push(release_info);
122 | }
123 |
124 | log::info!("Done checking GitHub API");
125 |
126 | Ok(release_info_vector)
127 | }
128 |
129 | /// Checks latest GitHub release and generates a announcement message for Discord based on it
130 | #[tauri::command]
131 | pub async fn generate_release_note_announcement() -> Result {
132 | let octocrab = octocrab::instance();
133 | let page = octocrab
134 | .repos("R2Northstar", "Northstar")
135 | .releases()
136 | .list()
137 | // Optional Parameters
138 | .per_page(1)
139 | .page(1u32)
140 | // Send the request
141 | .send()
142 | .await
143 | .unwrap();
144 |
145 | // Get newest element
146 | let latest_release_item = &page.items[0];
147 |
148 | // Extract the URL to the GitHub release note
149 | let github_release_link = latest_release_item.html_url.clone();
150 |
151 | // Extract release version number
152 | let current_ns_version = &latest_release_item.tag_name;
153 |
154 | // Extract changelog and format it
155 | let changelog = remove_markdown_links::remove_markdown_links(
156 | latest_release_item
157 | .body
158 | .as_ref()
159 | .unwrap()
160 | .split("**Contributors:**")
161 | .next()
162 | .unwrap()
163 | .trim(),
164 | );
165 |
166 | // Strings to insert for different sections
167 | // Hardcoded for now
168 | let general_info = "REPLACE ME";
169 | let modders_info = "Mod compatibility should not be impacted";
170 | let server_hosters_info = "REPLACE ME";
171 |
172 | let mut rng = rand::thread_rng();
173 | let attributes = vec![
174 | "adorable",
175 | "amazing",
176 | "beautiful",
177 | "blithsome",
178 | "brilliant",
179 | "compassionate",
180 | "dazzling",
181 | "delightful",
182 | "distinguished",
183 | "elegant",
184 | "enigmatic",
185 | "enthusiastic",
186 | "fashionable",
187 | "fortuitous",
188 | "friendly",
189 | "generous",
190 | "gleeful",
191 | "gorgeous",
192 | "handsome",
193 | "lively",
194 | "lovely",
195 | "lucky",
196 | "lustrous",
197 | "marvelous",
198 | "merry",
199 | "mirthful",
200 | "phantasmagorical",
201 | "pretty",
202 | "propitious",
203 | "ravishing",
204 | "sincere",
205 | "sophisticated fellow",
206 | "stupendous",
207 | "vivacious",
208 | "wonderful",
209 | "zestful",
210 | ];
211 |
212 | let selected_attribute = attributes.choose(&mut rng).unwrap();
213 |
214 | // Build announcement string
215 | let return_string = format!(
216 | r"Hello {selected_attribute} people <3
217 | **Northstar `{current_ns_version}` is out!**
218 |
219 | {general_info}
220 |
221 | __**Modders:**__
222 |
223 | {modders_info}
224 |
225 | __**Server hosters:**__
226 |
227 | {server_hosters_info}
228 |
229 | __**Changelog:**__
230 | ```
231 | {changelog}
232 | ```
233 | {github_release_link}
234 |
235 | Checkout #installation on how to install/update Northstar
236 | (the process is the same for both, using a Northstar installer like FlightCore, Viper, or VTOL is recommended over manual installation)
237 |
238 | If you do notice any bugs, please open an issue on Github or drop a message in the thread below
239 | "
240 | );
241 |
242 | // Return built announcement message
243 | Ok(return_string.to_string())
244 | }
245 |
--------------------------------------------------------------------------------
/src-tauri/src/lib.rs:
--------------------------------------------------------------------------------
1 | use std::{env, time::Duration};
2 |
3 | mod constants;
4 | mod development;
5 | mod github;
6 | mod mod_management;
7 | mod northstar;
8 | mod platform_specific;
9 | mod repair_and_verify;
10 | mod thunderstore;
11 | mod util;
12 |
13 | use serde::{Deserialize, Serialize};
14 | use tauri::Emitter;
15 | use tokio::time::sleep;
16 | use ts_rs::TS;
17 |
18 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
19 | #[ts(export)]
20 | struct NorthstarThunderstoreRelease {
21 | package: String,
22 | version: String,
23 | }
24 |
25 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
26 | #[ts(export)]
27 | pub struct NorthstarThunderstoreReleaseWrapper {
28 | label: String,
29 | value: NorthstarThunderstoreRelease,
30 | }
31 |
32 | #[cfg_attr(mobile, tauri::mobile_entry_point)]
33 | pub fn run() {
34 | // Setup logger
35 | let mut log_builder = pretty_env_logger::formatted_builder();
36 | log_builder.parse_filters("info");
37 | let logger = sentry_log::SentryLogger::with_dest(log_builder.build());
38 |
39 | log::set_boxed_logger(Box::new(logger)).unwrap();
40 | log::set_max_level(log::LevelFilter::Info);
41 |
42 | // Only enable Sentry crash logs on release
43 | #[cfg(not(debug_assertions))]
44 | let _guard = sentry::init((
45 | "https://f833732deb2240b0b2dc4abce97d0f1d@o1374052.ingest.sentry.io/6692177",
46 | sentry::ClientOptions {
47 | release: sentry::release_name!(),
48 | attach_stacktrace: true,
49 | ..Default::default()
50 | },
51 | ));
52 |
53 | let tauri_builder_res = tauri::Builder::default()
54 | .plugin(tauri_plugin_dialog::init())
55 | .plugin(tauri_plugin_updater::Builder::new().build())
56 | .plugin(tauri_plugin_store::Builder::new().build())
57 | .plugin(tauri_plugin_opener::init())
58 | .setup(|app| {
59 | let app_handle = app.handle().clone();
60 | tauri::async_runtime::spawn(async move {
61 | loop {
62 | sleep(Duration::from_millis(2000)).await;
63 | // println!("sending backend ping");
64 | app_handle.emit("backend-ping", "ping").unwrap();
65 | }
66 | });
67 | let app_handle = app.handle().clone();
68 | tauri::async_runtime::spawn(async move {
69 | loop {
70 | sleep(Duration::from_millis(2000)).await;
71 | app_handle
72 | .emit(
73 | "ea-app-running-ping",
74 | util::check_ea_app_or_origin_running(),
75 | )
76 | .unwrap();
77 | }
78 | });
79 | let app_handle = app.handle().clone();
80 | tauri::async_runtime::spawn(async move {
81 | loop {
82 | sleep(Duration::from_millis(2000)).await;
83 | app_handle
84 | .emit("northstar-running-ping", util::check_northstar_running())
85 | .unwrap();
86 | }
87 | });
88 |
89 | // Emit updated player and server count to GUI
90 | let app_handle = app.handle().clone();
91 | tauri::async_runtime::spawn(async move {
92 | loop {
93 | sleep(constants::REFRESH_DELAY).await;
94 | app_handle
95 | .emit(
96 | "northstar-statistics",
97 | util::get_server_player_count().await,
98 | )
99 | .unwrap();
100 | }
101 | });
102 |
103 | Ok(())
104 | })
105 | .manage(())
106 | .invoke_handler(tauri::generate_handler![
107 | development::install_git_main,
108 | github::compare_tags,
109 | github::get_list_of_tags,
110 | github::pull_requests::apply_launcher_pr,
111 | github::pull_requests::apply_mods_pr,
112 | github::pull_requests::get_launcher_download_link,
113 | github::pull_requests::get_pull_requests_wrapper,
114 | github::release_notes::check_is_flightcore_outdated,
115 | github::release_notes::generate_release_note_announcement,
116 | github::release_notes::get_newest_flightcore_version,
117 | github::release_notes::get_northstar_release_notes,
118 | mod_management::delete_northstar_mod,
119 | mod_management::delete_thunderstore_mod,
120 | mod_management::get_installed_mods_and_properties,
121 | mod_management::install_mod_wrapper,
122 | mod_management::set_mod_enabled_status,
123 | northstar::check_is_northstar_outdated,
124 | northstar::get_available_northstar_versions,
125 | northstar::get_northstar_version_number,
126 | northstar::install::find_game_install_location,
127 | northstar::install::install_northstar_wrapper,
128 | northstar::install::update_northstar,
129 | northstar::launch_northstar,
130 | northstar::profile::clone_profile,
131 | northstar::profile::delete_profile,
132 | northstar::profile::fetch_profiles,
133 | northstar::profile::validate_profile,
134 | platform_specific::check_cgnat,
135 | platform_specific::get_host_os,
136 | platform_specific::get_local_northstar_proton_wrapper_version,
137 | platform_specific::install_northstar_proton_wrapper,
138 | platform_specific::uninstall_northstar_proton_wrapper,
139 | repair_and_verify::clean_up_download_folder_wrapper,
140 | repair_and_verify::disable_all_but_core,
141 | repair_and_verify::get_log_list,
142 | repair_and_verify::verify_game_files,
143 | repair_and_verify::verify_install_location,
144 | thunderstore::query_thunderstore_packages_api,
145 | util::close_application,
146 | util::force_panic,
147 | util::get_flightcore_version_number,
148 | util::get_server_player_count,
149 | util::is_debug_mode,
150 | util::kill_northstar,
151 | util::open_repair_window,
152 | ])
153 | .run(tauri::generate_context!());
154 |
155 | match tauri_builder_res {
156 | Ok(()) => (),
157 | Err(err) => {
158 | // Failed to launch system native web view
159 |
160 | // Log error on Linux
161 | #[cfg(not(target_os = "windows"))]
162 | {
163 | log::error!("{err}");
164 | }
165 |
166 | // Log error on Windows
167 | // TODO show error dialog instead
168 | #[cfg(target_os = "windows")]
169 | {
170 | log::error!("{err}");
171 | }
172 | }
173 | };
174 | }
175 |
176 | /// Defines how Titanfall2 was installed (Steam, Origin, ...)
177 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
178 | #[ts(export)]
179 | pub enum InstallType {
180 | STEAM,
181 | ORIGIN,
182 | EAPLAY,
183 | UNKNOWN,
184 | }
185 |
186 | /// Object holding information of the Titanfall2 install, including
187 | /// - Install path
188 | /// - Active profile
189 | /// - Type of installation (Steam, Origin, ...)
190 | #[derive(Serialize, Deserialize, Debug, Clone)]
191 | pub struct GameInstall {
192 | pub game_path: String,
193 | pub profile: String,
194 | pub install_type: InstallType,
195 | }
196 |
197 | /// Object holding various information about a Northstar mod
198 | #[derive(Serialize, Deserialize, Debug, Clone, TS)]
199 | #[ts(export)]
200 | pub struct NorthstarMod {
201 | pub name: String,
202 | pub version: Option,
203 | pub thunderstore_mod_string: Option,
204 | pub enabled: bool,
205 | pub directory: String,
206 | }
207 |
--------------------------------------------------------------------------------
/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release, DO NOT REMOVE!!
2 | #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
3 |
4 | fn main() {
5 | tauri_app_lib::run()
6 | }
7 |
--------------------------------------------------------------------------------
/src-tauri/src/mod_management/plugins.rs:
--------------------------------------------------------------------------------
1 | /// Prompt on plugin
2 | /// Returns:
3 | /// - true: user accepted plugin install
4 | /// - false: user denied plugin install
5 | pub fn plugin_prompt() -> bool {
6 | log::error!("Plugin install cancelled");
7 | // TODO handle plugin installation again
8 | false
9 | }
10 |
--------------------------------------------------------------------------------
/src-tauri/src/northstar/profile.rs:
--------------------------------------------------------------------------------
1 | use crate::util::copy_dir_all;
2 | use crate::GameInstall;
3 |
4 | // These folders are part of Titanfall 2 and
5 | // should NEVER be used as a Profile
6 | const SKIP_PATHS: [&str; 8] = [
7 | "___flightcore-temp",
8 | "__overlay",
9 | "bin",
10 | "Core",
11 | "r2",
12 | "vpk",
13 | "platform",
14 | "Support",
15 | ];
16 |
17 | // A profile may have one of these to be detected
18 | const MAY_CONTAIN: [&str; 10] = [
19 | "mods/",
20 | "plugins/",
21 | "packages/",
22 | "logs/",
23 | "runtime/",
24 | "save_data/",
25 | "Northstar.dll",
26 | "enabledmods.json",
27 | "placeholder.playerdata.pdata",
28 | "LEGAL.txt",
29 | ];
30 |
31 | /// Returns a list of Profile names
32 | /// All the returned Profiles can be found relative to the game path
33 | #[tauri::command]
34 | pub fn fetch_profiles(game_install: GameInstall) -> Result, String> {
35 | let mut profiles: Vec = Vec::new();
36 |
37 | for content in MAY_CONTAIN {
38 | let pattern = format!("{}/*/{}", game_install.game_path, content);
39 | for e in glob::glob(&pattern).expect("Failed to read glob pattern") {
40 | let path = e.unwrap();
41 | let mut ancestors = path.ancestors();
42 |
43 | ancestors.next();
44 |
45 | let profile_path = std::path::Path::new(ancestors.next().unwrap());
46 | let profile_name = profile_path
47 | .file_name()
48 | .unwrap()
49 | .to_os_string()
50 | .into_string()
51 | .unwrap();
52 |
53 | if !profiles.contains(&profile_name) {
54 | profiles.push(profile_name);
55 | }
56 | }
57 | }
58 |
59 | Ok(profiles)
60 | }
61 |
62 | /// Validates if a given profile is actually a valid profile
63 | #[tauri::command]
64 | pub fn validate_profile(game_install: GameInstall, profile: String) -> bool {
65 | // Game files are never a valid profile
66 | // Prevent users with messed up installs from making it even worse
67 | if SKIP_PATHS.contains(&profile.as_str()) {
68 | return false;
69 | }
70 |
71 | log::info!("Validating Profile {}", profile);
72 |
73 | let profile_path = format!("{}/{}", game_install.game_path, profile);
74 | let profile_dir = std::path::Path::new(profile_path.as_str());
75 |
76 | profile_dir.is_dir()
77 | }
78 |
79 | #[tauri::command]
80 | pub fn delete_profile(game_install: GameInstall, profile: String) -> Result<(), String> {
81 | // Check if the Profile actually exists
82 | if !validate_profile(game_install.clone(), profile.clone()) {
83 | return Err(format!("{} is not a valid Profile", profile));
84 | }
85 |
86 | log::info!("Deleting Profile {}", profile);
87 |
88 | let profile_path = format!("{}/{}", game_install.game_path, profile);
89 |
90 | match std::fs::remove_dir_all(profile_path) {
91 | Ok(()) => Ok(()),
92 | Err(err) => Err(format!("Failed to delete Profile: {}", err)),
93 | }
94 | }
95 |
96 | /// Clones a profile by simply duplicating the folder under a new name
97 | #[tauri::command]
98 | pub fn clone_profile(
99 | game_install: GameInstall,
100 | old_profile: String,
101 | new_profile: String,
102 | ) -> Result<(), String> {
103 | // Check if the old Profile already exists
104 | if !validate_profile(game_install.clone(), old_profile.clone()) {
105 | return Err(format!("{} is not a valid Profile", old_profile));
106 | }
107 |
108 | // Check that new Profile does not already exist
109 | if validate_profile(game_install.clone(), new_profile.clone()) {
110 | return Err(format!("{} already exists", new_profile));
111 | }
112 |
113 | log::info!("Cloning Profile {} to {}", old_profile, new_profile);
114 |
115 | let old_profile_path = format!("{}/{}", game_install.game_path, old_profile);
116 | let new_profile_path = format!("{}/{}", game_install.game_path, new_profile);
117 |
118 | copy_dir_all(old_profile_path, new_profile_path).unwrap();
119 |
120 | Ok(())
121 | }
122 |
--------------------------------------------------------------------------------
/src-tauri/src/platform_specific/linux.rs:
--------------------------------------------------------------------------------
1 | // Linux specific code
2 |
3 | fn get_proton_dir() -> Result {
4 | let steam_dir = match steamlocate::SteamDir::locate() {
5 | Ok(result) => result,
6 | Err(_) => return Err("Unable to find Steam directory".to_string()),
7 | };
8 | let compat_dir = format!("{}/compatibilitytools.d", steam_dir.path().display());
9 |
10 | Ok(compat_dir)
11 | }
12 |
13 | /// Downloads and installs NS proton
14 | /// Assumes Steam install
15 | pub fn install_ns_proton() -> Result<(), String> {
16 | // Get latest NorthstarProton release
17 | let latest = match thermite::core::latest_release() {
18 | Ok(result) => result,
19 | Err(_) => return Err("Failed to fetch latest NorthstarProton release".to_string()),
20 | };
21 |
22 | let temp_dir = std::env::temp_dir();
23 | let path = format!("{}/nsproton-{}.tar.gz", temp_dir.display(), latest);
24 | let archive = match std::fs::File::create(path.clone()) {
25 | Ok(result) => result,
26 | Err(_) => return Err("Failed to allocate NorthstarProton archive on disk".to_string()),
27 | };
28 |
29 | // Download the latest Proton release
30 | log::info!("Downloading NorthstarProton to {}", path);
31 | match thermite::core::download_ns_proton(latest, archive) {
32 | Ok(_) => {}
33 | Err(_) => return Err("Failed to download NorthstarProton".to_string()),
34 | }
35 |
36 | log::info!("Finished Download");
37 |
38 | let compat_dir = get_proton_dir()?;
39 |
40 | match std::fs::create_dir_all(compat_dir.clone()) {
41 | Ok(_) => {}
42 | Err(_) => return Err("Failed to create compatibilitytools directory".to_string()),
43 | }
44 |
45 | let finished = match std::fs::File::open(path.clone()) {
46 | Ok(result) => result,
47 | Err(_) => return Err("Failed to open NorthstarProton archive".to_string()),
48 | };
49 |
50 | // Extract to Proton dir
51 | log::info!("Installing NorthstarProton to {}", compat_dir);
52 | match thermite::core::install_ns_proton(&finished, compat_dir) {
53 | Ok(_) => {}
54 | Err(_) => return Err("Failed to create install NorthstarProton".to_string()),
55 | }
56 | log::info!("Finished Installation");
57 | drop(finished);
58 |
59 | // We installed NSProton, lets ignore this if it fails
60 | let _ = std::fs::remove_file(path);
61 |
62 | Ok(())
63 | }
64 |
65 | /// Remove NS Proton
66 | pub fn uninstall_ns_proton() -> Result<(), String> {
67 | let compat_dir = get_proton_dir()?;
68 | let pattern = format!("{}/NorthstarProton*", compat_dir);
69 | for e in glob::glob(&pattern).expect("Failed to read glob pattern") {
70 | match e {
71 | Ok(path) => match std::fs::remove_dir_all(path.clone()) {
72 | Ok(_) => {}
73 | Err(_) => return Err(format!("Failed to remove {}", path.display())),
74 | },
75 | Err(e) => return Err(format!("Found unprocessable entry {}", e)),
76 | }
77 | }
78 |
79 | Ok(())
80 | }
81 |
82 | /// Get the latest installed NS Proton version
83 | pub fn get_local_ns_proton_version() -> Result {
84 | let compat_dir = get_proton_dir().unwrap();
85 | let pattern = format!("{}/NorthstarProton*/version", compat_dir);
86 |
87 | if let Some(e) = glob::glob(&pattern)
88 | .expect("Failed to read glob pattern")
89 | .next()
90 | {
91 | let version_content = std::fs::read_to_string(e.unwrap()).unwrap();
92 | let version = version_content.split(' ').nth(1).unwrap().to_string();
93 |
94 | return Ok(version);
95 | }
96 |
97 | Err("Northstar Proton is not installed".to_string())
98 | }
99 |
--------------------------------------------------------------------------------
/src-tauri/src/platform_specific/mod.rs:
--------------------------------------------------------------------------------
1 | #[cfg(target_os = "windows")]
2 | pub mod windows;
3 |
4 | #[cfg(target_os = "linux")]
5 | pub mod linux;
6 |
7 | /// Returns identifier of host OS FlightCore is running on
8 | #[tauri::command]
9 | pub fn get_host_os() -> String {
10 | std::env::consts::OS.to_string()
11 | }
12 |
13 | /// On Linux attempts to install NorthstarProton
14 | /// On Windows simply returns an error message
15 | #[tauri::command]
16 | pub async fn install_northstar_proton_wrapper() -> Result<(), String> {
17 | #[cfg(target_os = "linux")]
18 | return linux::install_ns_proton().map_err(|err| err.to_string());
19 |
20 | #[cfg(target_os = "windows")]
21 | Err("Not supported on Windows".to_string())
22 | }
23 |
24 | #[tauri::command]
25 | pub async fn uninstall_northstar_proton_wrapper() -> Result<(), String> {
26 | #[cfg(target_os = "linux")]
27 | return linux::uninstall_ns_proton();
28 |
29 | #[cfg(target_os = "windows")]
30 | Err("Not supported on Windows".to_string())
31 | }
32 |
33 | #[tauri::command]
34 | pub async fn get_local_northstar_proton_wrapper_version() -> Result {
35 | #[cfg(target_os = "linux")]
36 | return linux::get_local_ns_proton_version();
37 |
38 | #[cfg(target_os = "windows")]
39 | Err("Not supported on Windows".to_string())
40 | }
41 |
42 | /// Check whether the current device might be behind a CGNAT
43 | #[tauri::command]
44 | pub async fn check_cgnat() -> Result {
45 | #[cfg(target_os = "linux")]
46 | return Err("Not supported on Linux".to_string());
47 |
48 | #[cfg(target_os = "windows")]
49 | windows::check_cgnat().await
50 | }
51 |
--------------------------------------------------------------------------------
/src-tauri/src/platform_specific/windows.rs:
--------------------------------------------------------------------------------
1 | /// Windows specific code
2 | use anyhow::{anyhow, Result};
3 | use std::net::Ipv4Addr;
4 |
5 | #[cfg(target_os = "windows")]
6 | use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey};
7 |
8 | use crate::repair_and_verify::check_is_valid_game_path;
9 |
10 | /// Gets Titanfall2 install location on Origin
11 | pub fn origin_install_location_detection() -> Result {
12 | #[cfg(target_os = "windows")]
13 | {
14 | let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
15 | match hklm.open_subkey("SOFTWARE\\Respawn\\Titanfall2") {
16 | Ok(tf) => {
17 | let game_path_str: String = tf.get_value("Install Dir")?;
18 |
19 | match check_is_valid_game_path(&game_path_str) {
20 | Ok(()) => {
21 | return Ok(game_path_str.to_string());
22 | }
23 | Err(err) => {
24 | log::warn!("{err}");
25 | }
26 | }
27 | }
28 | Err(err) => {
29 | log::warn!("{err}");
30 | }
31 | }
32 | }
33 |
34 | Err(anyhow!("No Origin / EA App install path found"))
35 | }
36 |
37 | /// Check whether the current device might be behind a CGNAT
38 | pub async fn check_cgnat() -> Result {
39 | // Use external service to grap IP
40 | let url = "https://api.ipify.org";
41 | let response = reqwest::get(url).await.unwrap().text().await.unwrap();
42 |
43 | // Check if valid IPv4 address and return early if not
44 | if response.parse::().is_err() {
45 | return Err(format!("Not valid IPv4 address: {}", response));
46 | }
47 |
48 | let hops_count = run_tracert(&response)?;
49 | Ok(format!("Counted {} hops to {}", hops_count, response))
50 | }
51 |
52 | /// Count number of hops in tracert output
53 | fn count_hops(output: &str) -> usize {
54 | // Split the output into lines
55 | let lines: Vec<&str> = output.lines().collect();
56 |
57 | // Filter lines that appear to represent hops
58 | let hop_lines: Vec<&str> = lines
59 | .iter()
60 | .filter(|&line| line.contains("ms") || line.contains("*")) // TODO check if it contains just the `ms` surrounded by whitespace, otherwise it might falsely pick up some domain names as well
61 | .cloned()
62 | .collect();
63 |
64 | // Return the number of hops
65 | hop_lines.len()
66 | }
67 |
68 | /// Run `tracert`
69 | fn run_tracert(target_ip: &str) -> Result {
70 | // Ensure valid IPv4 address to avoid prevent command injection
71 | assert!(target_ip.parse::().is_ok());
72 |
73 | // Execute the `tracert` command
74 | let output = match std::process::Command::new("tracert")
75 | .arg("-4") // Force IPv4
76 | .arg("-d") // Prevent resolving intermediate IP addresses
77 | .arg("-w") // Set timeout to 1 second
78 | .arg("1000")
79 | .arg("-h") // Set max hop count
80 | .arg("5")
81 | .arg(target_ip)
82 | .output()
83 | {
84 | Ok(res) => res,
85 | Err(err) => return Err(format!("Failed running tracert: {}", err)),
86 | };
87 |
88 | // Check if the command was successful
89 | if output.status.success() {
90 | // Convert the output to a string
91 | let stdout =
92 | std::str::from_utf8(&output.stdout).expect("Invalid UTF-8 sequence in command output");
93 | println!("{}", stdout);
94 |
95 | // Count the number of hops
96 | let hop_count = count_hops(stdout);
97 | Ok(hop_count)
98 | } else {
99 | let stderr = std::str::from_utf8(&output.stderr)
100 | .expect("Invalid UTF-8 sequence in command error output");
101 | println!("{}", stderr);
102 | Err(format!("Failed collecting tracert output: {}", stderr))
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src-tauri/src/repair_and_verify/mod.rs:
--------------------------------------------------------------------------------
1 | use crate::mod_management::{get_enabled_mods, rebuild_enabled_mods_json, set_mod_enabled_status};
2 | /// Contains various functions to repair common issues and verifying installation
3 | use crate::{constants::CORE_MODS, GameInstall};
4 |
5 | /// Checks if is valid Titanfall2 install based on certain conditions
6 | #[tauri::command]
7 | pub async fn verify_install_location(game_path: String) -> bool {
8 | match check_is_valid_game_path(&game_path) {
9 | Ok(()) => true,
10 | Err(err) => {
11 | log::warn!("{}", err);
12 | false
13 | }
14 | }
15 | }
16 |
17 | /// Checks whether the provided path is a valid Titanfall2 gamepath by checking against a certain set of criteria
18 | pub fn check_is_valid_game_path(game_install_path: &str) -> Result<(), String> {
19 | let path_to_titanfall2_exe = format!("{game_install_path}/Titanfall2.exe");
20 | let is_correct_game_path = std::path::Path::new(&path_to_titanfall2_exe).exists();
21 | log::info!("Titanfall2.exe exists in path? {}", is_correct_game_path);
22 |
23 | // Exit early if wrong game path
24 | if !is_correct_game_path {
25 | return Err(format!("Incorrect game path \"{game_install_path}\"")); // Return error cause wrong game path
26 | }
27 | Ok(())
28 | }
29 |
30 | /// Verifies Titanfall2 game files
31 | #[tauri::command]
32 | pub fn verify_game_files(game_install: GameInstall) -> Result {
33 | dbg!(game_install);
34 | Err("TODO, not yet implemented".to_string())
35 | }
36 |
37 | /// Disables all mods except core ones
38 | /// Enables core mods if disabled
39 | #[tauri::command]
40 | pub fn disable_all_but_core(game_install: GameInstall) -> Result<(), String> {
41 | // Rebuild `enabledmods.json` first to ensure all mods are added
42 | rebuild_enabled_mods_json(&game_install)?;
43 |
44 | let current_mods = get_enabled_mods(&game_install)?;
45 |
46 | // Disable all mods, set core mods to enabled
47 | for (key, _value) in current_mods.as_object().unwrap() {
48 | if CORE_MODS.contains(&key.as_str()) {
49 | // This is a core mod, we do not want to disable it
50 | set_mod_enabled_status(game_install.clone(), key.to_string(), true)?;
51 | } else {
52 | // Not a core mod
53 | set_mod_enabled_status(game_install.clone(), key.to_string(), false)?;
54 | }
55 | }
56 |
57 | Ok(())
58 | }
59 |
60 | /// Installs the specified mod
61 | #[tauri::command]
62 | pub async fn clean_up_download_folder_wrapper(
63 | game_install: GameInstall,
64 | force: bool,
65 | ) -> Result<(), String> {
66 | match clean_up_download_folder(&game_install, force) {
67 | Ok(()) => Ok(()),
68 | Err(err) => Err(err.to_string()),
69 | }
70 | }
71 |
72 | /// Deletes download folder
73 | /// If `force` is FALSE, bails on non-empty folder
74 | /// If `force` is TRUE, deletes folder even if non-empty
75 | pub fn clean_up_download_folder(
76 | game_install: &GameInstall,
77 | force: bool,
78 | ) -> Result<(), anyhow::Error> {
79 | const TEMPORARY_DIRECTORIES: [&str; 4] = [
80 | "___flightcore-temp-download-dir",
81 | "___flightcore-temp/download-dir",
82 | "___flightcore-temp/extract-dir",
83 | "___flightcore-temp",
84 | ];
85 |
86 | for directory in TEMPORARY_DIRECTORIES {
87 | // Get download directory
88 | let download_directory = format!("{}/{}/", game_install.game_path, directory);
89 |
90 | // Check if files in folder
91 | let download_dir_contents = match std::fs::read_dir(download_directory.clone()) {
92 | Ok(contents) => contents,
93 | Err(_) => continue,
94 | };
95 |
96 | let mut count = 0;
97 | download_dir_contents.for_each(|_| count += 1);
98 |
99 | if count > 0 && !force {
100 | // Skip folder if not empty
101 | log::warn!("Folder not empty, not deleting: {directory}");
102 | continue;
103 | }
104 |
105 | // Delete folder
106 | std::fs::remove_dir_all(download_directory)?;
107 | }
108 | Ok(())
109 | }
110 |
111 | /// Get list of Northstar logs
112 | #[tauri::command]
113 | pub fn get_log_list(game_install: GameInstall) -> Result, String> {
114 | let ns_log_folder = format!("{}/{}/logs", game_install.game_path, game_install.profile);
115 |
116 | // List files in logs folder
117 | let paths = match std::fs::read_dir(ns_log_folder) {
118 | Ok(paths) => paths,
119 | Err(_err) => return Err("No logs folder found".to_string()),
120 | };
121 |
122 | // Stores paths of log files
123 | let mut log_files: Vec = Vec::new();
124 |
125 | for path in paths {
126 | let path = path.unwrap().path();
127 | if path.display().to_string().contains("nslog") {
128 | log_files.push(path);
129 | }
130 | }
131 |
132 | if !log_files.is_empty() {
133 | Ok(log_files)
134 | } else {
135 | Err("No logs found".to_string())
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src-tauri/src/thunderstore/mod.rs:
--------------------------------------------------------------------------------
1 | //! For interacting with Thunderstore API
2 | use crate::constants::{APP_USER_AGENT, BLACKLISTED_MODS};
3 | use serde::{Deserialize, Serialize};
4 | use std::collections::HashSet;
5 | use ts_rs::TS;
6 |
7 | #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
8 | #[ts(export)]
9 | pub struct ThunderstoreMod {
10 | pub name: String,
11 | pub full_name: String,
12 | pub owner: String,
13 | pub package_url: String,
14 | pub date_created: String,
15 | pub date_updated: String,
16 | pub uuid4: String,
17 | pub rating_score: i32,
18 | pub is_pinned: bool,
19 | pub is_deprecated: bool,
20 | pub has_nsfw_content: bool,
21 | pub categories: Vec,
22 | pub versions: Vec,
23 | }
24 |
25 | #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
26 | #[ts(export)]
27 | pub struct ThunderstoreModVersion {
28 | pub name: String,
29 | pub full_name: String,
30 | pub description: String,
31 | pub icon: String,
32 | pub version_number: String,
33 | pub dependencies: Vec,
34 | pub download_url: String,
35 | pub downloads: i32,
36 | pub date_created: String,
37 | pub website_url: String,
38 | pub is_active: bool,
39 | pub uuid4: String,
40 | pub file_size: i64,
41 | }
42 |
43 | /// Performs actual fetch from Thunderstore and returns response
44 | async fn fetch_thunderstore_packages() -> Result {
45 | log::info!("Fetching Thunderstore API");
46 |
47 | // Fetches
48 | let url = "https://northstar.thunderstore.io/api/v1/package/";
49 |
50 | let client = reqwest::Client::new();
51 | client
52 | .get(url)
53 | .header(reqwest::header::USER_AGENT, APP_USER_AGENT)
54 | .send()
55 | .await?
56 | .text()
57 | .await
58 | }
59 |
60 | /// Queries Thunderstore packages API
61 | #[tauri::command]
62 | pub async fn query_thunderstore_packages_api() -> Result, String> {
63 | let res = match fetch_thunderstore_packages().await {
64 | Ok(res) => res,
65 | Err(err) => {
66 | let warn_response = format!("Couldn't fetch from Thunderstore: {err}");
67 | log::warn!("{warn_response}");
68 | return Err(warn_response);
69 | }
70 | };
71 |
72 | // Parse response
73 | let parsed_json: Vec = match serde_json::from_str(&res) {
74 | Ok(res) => res,
75 | Err(err) => return Err(err.to_string()),
76 | };
77 |
78 | // Remove some mods from listing
79 | let to_remove_set: HashSet<&str> = BLACKLISTED_MODS.iter().copied().collect();
80 | let filtered_packages = parsed_json
81 | .into_iter()
82 | .filter(|package| !to_remove_set.contains(&package.full_name.as_ref()))
83 | .collect::>();
84 |
85 | Ok(filtered_packages)
86 | }
87 |
--------------------------------------------------------------------------------
/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.tauri.app/config/2",
3 | "build": {
4 | "beforeBuildCommand": "cd src-vue && npm run build",
5 | "beforeDevCommand": "cd src-vue && npm run dev",
6 | "devUrl": "http://localhost:1420/",
7 | "frontendDist": "../src-vue/dist"
8 | },
9 | "productName": "FlightCore",
10 | "version": "3.0.6",
11 | "identifier": "com.github.r2northstartools.flightcore",
12 | "app": {
13 | "windows": [
14 | {
15 | "title": "FlightCore",
16 | "decorations": false,
17 | "width": 1010,
18 | "height": 600
19 | }
20 | ],
21 | "security": {
22 | "csp": null
23 | }
24 | },
25 | "bundle": {
26 | "active": true,
27 | "createUpdaterArtifacts": "v1Compatible",
28 | "targets": "all",
29 | "icon": [
30 | "icons/32x32.png",
31 | "icons/128x128.png",
32 | "icons/128x128@2x.png",
33 | "icons/icon.icns",
34 | "icons/icon.ico"
35 | ]
36 | },
37 | "plugins": {
38 | "updater": {
39 | "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEVBNjM3NzJGRDgxMTU4NUUKUldSZVdCSFlMM2RqNmdhK3pIZjhEYWg2WnZGSFJqdkhLSHNOSjNhaW5VQVFLaHV3YWFDTnFKWWQK",
40 | "endpoints": [
41 | "https://github.com/R2NorthstarTools/FlightCore/releases/latest/download/latest-release.json"
42 | ]
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src-vue/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src-vue/README.md:
--------------------------------------------------------------------------------
1 | # FlightCore UI
2 |
3 | This folder holds FlightCore's interface repository.
4 |
5 | This is a [Vue (v4)](https://vuejs.org/) project, using [Element Plus](https://element-plus.org/en-US/) component library.
6 |
7 | ## Development
8 |
9 | ```shell
10 | # Install dependencies
11 | npm install
12 |
13 | # Run in development mode
14 | npm run dev
15 |
16 | # Build for production
17 | npm run build
18 | ```
19 |
--------------------------------------------------------------------------------
/src-vue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Vue + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src-vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "src-vue",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vue-tsc --noEmit && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@element-plus/icons-vue": "^2.0.9",
13 | "element-plus": "^2.7.8",
14 | "marked": "^14.1.3",
15 | "@tauri-apps/plugin-dialog": "^2.0.0",
16 | "@tauri-apps/plugin-shell": "^2.0.0",
17 | "@tauri-apps/plugin-store": "^2.2.0",
18 | "@tauri-apps/plugin-updater": "^2.5.1",
19 | "vue": "^3.4.35",
20 | "vue-i18n": "^9.13.1",
21 | "vue-router": "^4.4.3",
22 | "vuex": "^4.0.2"
23 | },
24 | "devDependencies": {
25 | "@vitejs/plugin-vue": "^3.1.0",
26 | "typescript": "^5.6.3",
27 | "vite": "^3.1.0",
28 | "vue-tsc": "^2.1.10"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src-vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
55 |
56 |
57 |
58 |
59 |
60 |
83 |
84 |
85 |
86 |
87 |
88 |
216 |
--------------------------------------------------------------------------------
/src-vue/src/assets/1009235.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-vue/src/assets/1009235.jpg
--------------------------------------------------------------------------------
/src-vue/src/assets/mp_colony020033.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-vue/src/assets/mp_colony020033.jpg
--------------------------------------------------------------------------------
/src-vue/src/assets/thunderstore-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-vue/src/assets/thunderstore-icon.png
--------------------------------------------------------------------------------
/src-vue/src/assets/wallpaperflare.com_wallpaper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/R2NorthstarTools/FlightCore/f0e46c4dd790ed9bed4e032e46e710f52e75618d/src-vue/src/assets/wallpaperflare.com_wallpaper.jpg
--------------------------------------------------------------------------------
/src-vue/src/components/InstallProgressBar.vue:
--------------------------------------------------------------------------------
1 |
72 |
73 |
74 |
82 |
83 |
84 |
85 |
104 |
--------------------------------------------------------------------------------
/src-vue/src/components/LanguageSelector.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
13 |
14 |
15 |
76 |
--------------------------------------------------------------------------------
/src-vue/src/components/LocalModCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ mod.name }}
(v{{ mod.version }})
5 |
12 |
13 |
14 |
21 |
27 |
28 |
29 | {{ $t('mods.local.delete') }}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
95 |
96 |
121 |
--------------------------------------------------------------------------------
/src-vue/src/components/ModsMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
56 |
57 |
58 |
90 |
91 |
142 |
--------------------------------------------------------------------------------
/src-vue/src/components/NotificationButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
63 |
64 |
82 |
--------------------------------------------------------------------------------
/src-vue/src/components/PlayButton.vue:
--------------------------------------------------------------------------------
1 |
95 |
96 |
97 |
98 |
101 | {{ playButtonLabel }}
102 |
103 |
105 |
110 |
116 |
117 |
118 |
119 |
120 |
121 |
158 |
--------------------------------------------------------------------------------
/src-vue/src/components/PullRequestsSelector.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Launcher PRs
7 | false">
8 |
9 |
10 |
11 |
19 |
20 |
26 | Install
27 | Download
28 |
29 | {{ pull_request.number }}: {{ pull_request.title }}
30 |
31 | {{ label }}
32 |
33 |
34 | No matching PR found.
35 |
36 |
37 |
38 |
39 |
40 | Mods PRs
41 | false">
42 |
43 |
44 |
45 | Mod PRs are installed into a separate profile. Make sure to launch via
46 | 'r2ns-launch-mod-pr-version.bat' or via '-profile=R2Northstar-PR-test-managed-folder' to actually
47 | run the PR version!
48 |
49 |
50 |
51 |
59 |
60 |
66 | Install
67 | Download
68 |
69 | {{ pull_request.number }}: {{ pull_request.title }}
70 |
71 | {{ label }}
72 |
73 |
74 | No matching PR found.
75 |
76 |
77 |
78 |
79 |
80 |
81 |
156 |
157 |
182 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/da.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "changelog": "Ændringslog",
4 | "mods": "Mods",
5 | "settings": "Indstillinger",
6 | "dev": "Dev",
7 | "play": "Spil"
8 | },
9 | "generic": {
10 | "yes": "Ja",
11 | "no": "Nej",
12 | "error": "Fejl",
13 | "cancel": "afbryd",
14 | "informationShort": "Info",
15 | "downloading": "Henter",
16 | "success": "Succes",
17 | "extracting": "Udpakker",
18 | "done": "Færdig"
19 | },
20 | "play": {
21 | "button": {
22 | "select_game_dir": "Vælg Titanfall2 spil mappe",
23 | "install": "Installere",
24 | "installing": "Installer...",
25 | "update": "Opdater",
26 | "updating": "Opdatere...",
27 | "ready_to_play": "Start spil",
28 | "northstar_is_running": "Spillet køre"
29 | },
30 | "unknown_version": "Ukendt version",
31 | "see_patch_notes": "Se patch noter",
32 | "players": "Spillere",
33 | "servers": "Servere",
34 | "northstar_running": "Northstar køre",
35 | "ea_app_running": "EA appen køre",
36 | "unable_to_load_playercount": "Kan ikke hente antallet af spillere"
37 | },
38 | "mods": {
39 | "local": {
40 | "no_mods": "Ingen mods blev fundet.",
41 | "delete_confirm": "Er du sikker på at du vil slette dette mod?",
42 | "delete": "Slet",
43 | "success_deleting": "Sletningen af {modName} lykkedes",
44 | "part_of_ts_mod": "Dette Northstar mod er en del af et Thunderstore mod"
45 | },
46 | "online": {
47 | "no_match": "Der er ikke fundet nogen matchende mod.",
48 | "try_another_search": "Prøv en anden søgning!"
49 | },
50 | "menu": {
51 | "local": "Lokal",
52 | "online": "Online",
53 | "filter": "Filter",
54 | "search": "Søg",
55 | "sort_mods": "Sorter mods",
56 | "select_categories": "Vælg kategorier",
57 | "sort": {
58 | "name_asc": "navn (A til Z)",
59 | "name_desc": "navn (Z til A)",
60 | "date_asc": "Dato (fra ældste)",
61 | "most_downloaded": "Mest hentet",
62 | "top_rated": "bedst bedømt",
63 | "date_desc": "Dato (fra nyeste)"
64 | }
65 | },
66 | "card": {
67 | "button": {
68 | "being_installed": "Installerer...",
69 | "being_updated": "Opdaterer...",
70 | "installed": "Installeret",
71 | "install": "Installere",
72 | "outdated": "Opdater"
73 | },
74 | "by": "af",
75 | "more_info": "Mere info",
76 | "remove": "Fjern mod",
77 | "remove_dialog_title": "Advarsel",
78 | "remove_success": "Fjernet {modName}",
79 | "install_success": "Installeret {modName}",
80 | "remove_dialog_text": "Fjern Thunderstore mod?"
81 | }
82 | },
83 | "settings": {
84 | "manage_install": "Administrer installation",
85 | "choose_folder": "Vælg installationsmappe",
86 | "open_game_folder": "Åben mappe",
87 | "nb_ts_mods_per_page": "Antal Thunderstore-mods pr. side",
88 | "nb_ts_mods_reset": "Nulstil til standard",
89 | "language": "Sprog",
90 | "language_select": "Vælg dit yndlingssprog",
91 | "about": "Om:",
92 | "flightcore_version": "FlightCore version:",
93 | "testing": "Tester:",
94 | "enable_test_channels": "Aktiver testudgivelseskanaler",
95 | "dev_mode_enabled_title": "Pas på!",
96 | "dev_mode_enabled_text": "Udviklertilstand aktiveret.",
97 | "show_deprecated_mods": "Vis forældede Thunderstore-mods",
98 | "show_deprecated_mods_desc2": "Pas på, sådanne mods er normalt forældet af en god grund.",
99 | "profile": {
100 | "active": "Aktiv profil",
101 | "edit": "Rediger profiler",
102 | "dialog": {
103 | "title": "Profiler"
104 | }
105 | },
106 | "repair": {
107 | "title": "Reparere",
108 | "open_window": "Åbn reparationsvinduet",
109 | "window": {
110 | "title": "FlightCore reparationsvinduet",
111 | "disable_all_but_core": "Deaktiver alle undtagen kernemods",
112 | "disable_all_but_core_success": "Deaktiverede alle mods undtagen kernemods",
113 | "disable_modsettings": "Deaktiver ModSettings mod",
114 | "disable_modsettings_success": "Deaktiver ModSettings mod",
115 | "force_reinstall_ns": "Tving geninstallation Northstar",
116 | "force_delete_temp_dl": "Tving sletning af midlertidig download-mappe",
117 | "delete_persistent_store": "Slet FlightCore persistent indhold",
118 | "reinstall_title": "Tving geninstallation af Northstar",
119 | "reinstall_text": "Vent lidt",
120 | "reinstall_success": "Northstar blev geninstalleret",
121 | "warning": "Dette vindue indeholder forskellige funktioner til at reparere almindelige problemer med Northstar og FlightCore.",
122 | "kill_northstar_process": "Dræb, der kører Northstar/Titanfall2-processen"
123 | }
124 | },
125 | "nb_ts_mods_per_page_desc1": "Dette har en indvirkning på skærmydelsen, når du gennemser Thunderstore-mods.",
126 | "nb_ts_mods_per_page_desc2": "Indstil denne værdi til 0 for at deaktivere paginering.",
127 | "show_deprecated_mods_desc1": "Dette giver dig mulighed for at se forældede mods i online-mods-samlingen."
128 | },
129 | "notification": {
130 | "game_folder": {
131 | "new": {
132 | "title": "Ny spil mappe",
133 | "text": "Spilmappen blev opdateret."
134 | },
135 | "wrong": {
136 | "title": "Forkert mappe",
137 | "text": "Den valgte mappe er ikke en gyldig Titanfall2 Installation."
138 | },
139 | "not_found": {
140 | "title": "Titanfall2 ikke fundet!",
141 | "text": "Vælg venligst installationsstedet manuelt"
142 | }
143 | },
144 | "profile": {
145 | "invalid": {
146 | "title": "Ugyldig profil",
147 | "text": "Den profil, du forsøgte at skifte til, er ikke længere gyldig."
148 | }
149 | },
150 | "flightcore_outdated": {
151 | "title": "FlightCore forældet!",
152 | "text": "Opdater venligst FlightCore.\nKører forældet version {oldVersion}.\nNyeste er {newVersion}!"
153 | }
154 | },
155 | "channels": {
156 | "release": {
157 | "switch": {
158 | "text": "Skiftet udgivelseskanal til \"{canal}\"."
159 | }
160 | },
161 | "names": {
162 | "Northstar": "Northstar",
163 | "NorthstarReleaseCandidate": "Northstar udgivelseskandidat"
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "play": "Play",
4 | "changelog": "Changelog",
5 | "mods": "Mods",
6 | "settings": "Settings",
7 | "dev": "Dev"
8 | },
9 |
10 | "generic": {
11 | "yes": "Yes",
12 | "no": "No",
13 | "error": "Error",
14 | "confirm": "Confirm",
15 | "cancel": "Cancel",
16 | "informationShort": "Info",
17 | "downloading": "Downloading",
18 | "extracting": "Extracting",
19 | "done": "Done",
20 | "success": "Success"
21 | },
22 |
23 | "play": {
24 | "button": {
25 | "northstar_is_running": "Game is running",
26 | "select_game_dir": "Select Titanfall2 game folder",
27 | "install": "Install",
28 | "installing": "Installing...",
29 | "update": "Update",
30 | "updating": "Updating...",
31 | "ready_to_play": "Launch game"
32 | },
33 |
34 | "unknown_version": "Unknown version",
35 | "see_patch_notes": "see patch notes",
36 | "players": "players",
37 | "servers": "servers",
38 | "unable_to_load_playercount": "Unable to load playercount",
39 | "northstar_running": "Northstar is running:",
40 | "ea_app_running": "EA App is running:"
41 | },
42 |
43 | "mods": {
44 | "local": {
45 | "no_mods": "No mods were found.",
46 | "delete_confirm": "Are you sure to delete this mod?",
47 | "delete": "Delete",
48 | "part_of_ts_mod": "This Northstar mod is part of a Thunderstore mod",
49 | "success_deleting": "Success deleting {modName}"
50 | },
51 |
52 | "online": {
53 | "no_match": "No matching mod has been found.",
54 | "try_another_search": "Try another search!"
55 | },
56 |
57 | "menu": {
58 | "local": "Local",
59 | "online": "Online",
60 | "filter": "Filter",
61 | "search": "Search",
62 | "sort_mods": "Sort mods",
63 | "select_categories": "Select categories",
64 |
65 | "sort": {
66 | "name_asc": "By name (A to Z)",
67 | "name_desc": "By name (Z to A)",
68 | "date_asc": "By date (from oldest)",
69 | "date_desc": "By date (from newest)",
70 | "most_downloaded": "Most downloaded",
71 | "top_rated": "Top rated"
72 | }
73 | },
74 |
75 | "card": {
76 | "button": {
77 | "being_installed": "Installing...",
78 | "being_updated": "Updating...",
79 | "installed": "Installed",
80 | "install": "Install",
81 | "outdated": "Update"
82 | },
83 |
84 | "by": "by",
85 | "more_info": "More info",
86 | "remove": "Remove mod",
87 | "remove_dialog_title": "Warning",
88 | "remove_dialog_text": "Delete Thunderstore mod?",
89 | "remove_success": "Removed {modName}",
90 | "install_success": "Installed {modName}"
91 | }
92 | },
93 |
94 | "settings": {
95 | "manage_install": "Manage installation",
96 | "choose_folder": "Choose installation folder",
97 | "open_game_folder": "Open Folder",
98 | "nb_ts_mods_per_page": "Number of Thunderstore mods per page",
99 | "nb_ts_mods_per_page_desc1": "This has an impact on display performances when browsing Thunderstore mods.",
100 | "nb_ts_mods_per_page_desc2": "Set this value to 0 to disable pagination.",
101 | "nb_ts_mods_reset": "Reset to default",
102 | "language": "Language",
103 | "language_select": "Select your favorite language",
104 | "about": "About:",
105 | "flightcore_version": "FlightCore version:",
106 | "testing": "Testing:",
107 | "enable_test_channels": "Enable testing release channels",
108 | "dev_mode_enabled_title": "Watch out!",
109 | "dev_mode_enabled_text": "Developer mode enabled.",
110 | "show_deprecated_mods": "Show deprecated Thunderstore mods",
111 | "show_deprecated_mods_desc1": "This allows you to see deprecated mods in the online mods collection.",
112 | "show_deprecated_mods_desc2": "Watch out, such mods are usually deprecated for a good reason.",
113 | "show_nsfw_mods": "Show NSFW Thunderstore mods",
114 |
115 | "profile": {
116 | "active": "Active Profile",
117 | "edit": "Edit Profiles",
118 |
119 | "dialog": {
120 | "title": "Profiles",
121 | "delete_confirm": "Are you sure to delete this profile?",
122 | "delete": "Delete",
123 | "clone": "Clone",
124 | "new_profile_name": "Enter the new Profile name",
125 | "create_empty": "New Profile"
126 | }
127 | },
128 |
129 | "repair": {
130 | "title": "Repair",
131 | "open_window": "Open repair window",
132 |
133 | "window": {
134 | "title": "FlightCore repair window",
135 | "warning": "This window contains various functionality to repair common issues with Northstar and FlightCore.",
136 | "disable_all_but_core": "Disable all but core mods",
137 | "disable_all_but_core_success": "Disabled all mods but core",
138 | "disable_modsettings": "Disable ModSettings mod",
139 | "disable_modsettings_success": "Disabled ModSettings mod",
140 | "force_reinstall_ns": "Force reinstall Northstar",
141 | "force_delete_temp_dl": "Force delete temp download folder",
142 | "delete_persistent_store": "Delete FlightCore persistent store",
143 | "kill_northstar_process": "Kill running Northstar/Titanfall2 process",
144 | "reinstall_title": "Force reinstalling Northstar",
145 | "reinstall_text": "Please wait",
146 | "reinstall_success": "Successfully reinstalled Northstar"
147 | }
148 | }
149 | },
150 |
151 | "notification": {
152 | "date_prefix": "at",
153 | "no_new": {
154 | "title": "Up-to-date",
155 | "text": "Nothing to see here!"
156 | },
157 |
158 | "game_folder": {
159 | "new": {
160 | "title": "New game folder",
161 | "text": "Game folder was successfully updated."
162 | },
163 |
164 | "wrong": {
165 | "title": "Wrong folder",
166 | "text": "Selected folder is not a valid Titanfall2 install."
167 | },
168 |
169 | "not_found": {
170 | "title": "Titanfall2 not found!",
171 | "text": "Please manually select install location"
172 | }
173 | },
174 |
175 | "profile": {
176 | "invalid": {
177 | "title": "Invalid Profile",
178 | "text": "The profile you tried to switch to is no longer valid."
179 | }
180 | },
181 |
182 | "flightcore_outdated": {
183 | "title": "FlightCore outdated!",
184 | "text": "Please update FlightCore.\nRunning outdated version {oldVersion}.\nNewest is {newVersion}!"
185 | }
186 | },
187 |
188 | "channels": {
189 | "release": {
190 | "switch": {
191 | "text": "Switched release channel to \"{canal}\"."
192 | }
193 | },
194 |
195 | "names": {
196 | "Northstar": "Northstar",
197 | "NorthstarReleaseCandidate": "Northstar release candidate"
198 | }
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "mods": "Modificaciones",
4 | "settings": "Opciones",
5 | "dev": "Desarrollador",
6 | "play": "Jugar",
7 | "changelog": "Cambios"
8 | },
9 | "generic": {
10 | "yes": "Sí",
11 | "no": "No",
12 | "error": "Error",
13 | "cancel": "Cancelar",
14 | "informationShort": "Información",
15 | "extracting": "Extrayendo",
16 | "done": "Listo",
17 | "success": "Éxito",
18 | "downloading": "Descargando",
19 | "confirm": "Confirmar"
20 | },
21 | "play": {
22 | "button": {
23 | "northstar_is_running": "El juego ya se está ejecutando",
24 | "install": "Instalar",
25 | "update": "Actualizar",
26 | "select_game_dir": "Seleccione carpeta base de Titanfall 2",
27 | "ready_to_play": "Jugar ahora",
28 | "installing": "Instalando...",
29 | "updating": "Actualizando..."
30 | },
31 | "ea_app_running": "La aplicación de EA ya se está ejecutando:",
32 | "unknown_version": "Versión Desconocida",
33 | "see_patch_notes": "Ver las notas del parche",
34 | "players": "jugadores",
35 | "servers": "servidores",
36 | "northstar_running": "Northstar ya se está ejecutando:",
37 | "unable_to_load_playercount": "Cantidad de jugadores no disponible"
38 | },
39 | "mods": {
40 | "local": {
41 | "no_mods": "No hay mods encontrados.",
42 | "delete_confirm": "¿Estás segur@ que quieres eliminar este mod?",
43 | "delete": "Eliminar",
44 | "success_deleting": "{modName} Ha sido eliminado correctamente",
45 | "part_of_ts_mod": "Este mod de Northstar es parte de un mod de la ThunderStore"
46 | },
47 | "online": {
48 | "no_match": "No hay mods coincidentes.",
49 | "try_another_search": "Intente otra busqueda!"
50 | },
51 | "menu": {
52 | "local": "Local",
53 | "online": "En línea",
54 | "filter": "FIltro",
55 | "search": "Búsqueda",
56 | "sort_mods": "Ordenar mods",
57 | "select_categories": "Seleccionar categorías",
58 | "sort": {
59 | "name_asc": "Por nombre (de la A a la Z)",
60 | "date_asc": "Por fecha (desde la más antigua)",
61 | "date_desc": "Por fecha (desde la más reciente)",
62 | "most_downloaded": "Los más descargados",
63 | "top_rated": "Mejor valorados",
64 | "name_desc": "Por nombre (de la Z a la A)"
65 | }
66 | },
67 | "card": {
68 | "button": {
69 | "being_installed": "Instalando...",
70 | "being_updated": "Actualizando...",
71 | "installed": "Instalado",
72 | "outdated": "Actualizar",
73 | "install": "Instalar"
74 | },
75 | "by": "por",
76 | "remove": "Quitar mod",
77 | "remove_dialog_title": "Advertencia",
78 | "remove_dialog_text": "Eliminar mod de la ThunderStore?",
79 | "install_success": "{modName} Instalado",
80 | "more_info": "Mas información",
81 | "remove_success": "{modName} Ha sido eliminado"
82 | }
83 | },
84 | "settings": {
85 | "manage_install": "Administrar instalación",
86 | "choose_folder": "Elegir carpeta de instalación",
87 | "open_game_folder": "Abrir carpeta",
88 | "nb_ts_mods_per_page": "Numero de mods por página de ThunderStore",
89 | "nb_ts_mods_per_page_desc2": "Poner valor en 0 para desactivar la paginación.",
90 | "nb_ts_mods_reset": "Reestablecer por defecto",
91 | "language": "Idioma",
92 | "language_select": "Seleccionar idioma favorito",
93 | "about": "Acerca de:",
94 | "flightcore_version": "Versión de FlightCore:",
95 | "testing": "Probando:",
96 | "enable_test_channels": "Activar liberación de canales",
97 | "dev_mode_enabled_title": "¡Cuidado!",
98 | "dev_mode_enabled_text": "Modo de desarrollador activado.",
99 | "show_deprecated_mods_desc1": "Esto permite ver mods obsoletos de la colección online de ThunderStore.",
100 | "show_deprecated_mods_desc2": "Cuidado, estos mods suelen estar obsoletos por una buena razón.",
101 | "profile": {
102 | "active": "Perfil activo",
103 | "edit": "Editar perfiles",
104 | "dialog": {
105 | "title": "Perfiles",
106 | "delete_confirm": "Eliminar Perfil?",
107 | "delete": "Eliminar",
108 | "clone": "Duplicar"
109 | }
110 | },
111 | "repair": {
112 | "title": "Reparar",
113 | "window": {
114 | "title": "Ventana de reparación de FlightCore",
115 | "disable_all_but_core": "Desactivar todos los mods excepto los principales",
116 | "disable_all_but_core_success": "Desactivados todos los mods excepto el núcleo",
117 | "disable_modsettings": "Desactivar ModSettings",
118 | "disable_modsettings_success": "ModSettings desactivado",
119 | "force_reinstall_ns": "Forzar reinstalación de Northstar",
120 | "force_delete_temp_dl": "Forzar la eliminación de la carpeta temporal de descargas",
121 | "delete_persistent_store": "Borrar el almacén persistente de FlightCore",
122 | "reinstall_title": "Forzar la reinstalación de Northstar",
123 | "reinstall_text": "Espere, por favor",
124 | "reinstall_success": "Northstar reinstalado con éxito",
125 | "warning": "Esta ventana tiene varias funciones para reparar problemas comunes con Northstar y FlightCore.",
126 | "kill_northstar_process": "Finalizar proceso de Northstar/Titanfall 2"
127 | },
128 | "open_window": "Abrir la ventana de reparación"
129 | },
130 | "nb_ts_mods_per_page_desc1": "Esto puede tener impactos en fluidez al buscar mods en la ThunderStore.",
131 | "show_deprecated_mods": "Mostrar mods the ThunderStore obsoletos"
132 | },
133 | "notification": {
134 | "game_folder": {
135 | "new": {
136 | "title": "Nueva carpeta de juego",
137 | "text": "La carpeta de juego fue actualizada exitosamente."
138 | },
139 | "wrong": {
140 | "title": "Carpeta equivocada",
141 | "text": "La carpeta seleccionada no es una carpeta de Titanfall2 válida."
142 | },
143 | "not_found": {
144 | "title": "Titanfall 2 no encontrado!",
145 | "text": "Por favor seleccione manualmente el lugar de instalación"
146 | }
147 | },
148 | "profile": {
149 | "invalid": {
150 | "title": "Perfil inválido",
151 | "text": "El perfil de cambio anterior ya no es válido."
152 | }
153 | },
154 | "flightcore_outdated": {
155 | "title": "FlightCore desactualizado!",
156 | "text": "Por favor actualize FlightCore.\nEsta versión esta desactualizada {oldVersion}\nLa versión mas nueva es {newVersion}!"
157 | },
158 | "no_new": {
159 | "title": "Al día",
160 | "text": "Nada que ver aquí!"
161 | },
162 | "date_prefix": "en"
163 | },
164 | "channels": {
165 | "release": {
166 | "switch": {
167 | "text": "El canal seleccionado se cambió a \"{canal}\"."
168 | }
169 | },
170 | "names": {
171 | "Northstar": "Northstar",
172 | "NorthstarReleaseCandidate": "Candidato de nueva versión de Northstar"
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/it.json:
--------------------------------------------------------------------------------
1 | {
2 | "generic": {
3 | "yes": "Si",
4 | "no": "No",
5 | "error": "Errore",
6 | "cancel": "Cancella",
7 | "downloading": "Scaricando",
8 | "extracting": "Estraendo",
9 | "done": "Fatto",
10 | "success": "Successo",
11 | "informationShort": "Info",
12 | "confirm": "Conferma"
13 | },
14 | "play": {
15 | "unknown_version": "Versione sconosciuta",
16 | "unable_to_load_playercount": "Impossibile caricare numero giocatori",
17 | "northstar_running": "Northstar sta andando:",
18 | "origin_running": "Origin sta andando:",
19 | "see_patch_notes": "guarda le note della patch",
20 | "players": "Giocatori",
21 | "servers": "Server",
22 | "button": {
23 | "northstar_is_running": "Il Gioco sta andando",
24 | "install": "Installa",
25 | "installing": "Installazione...",
26 | "update": "Aggiorna",
27 | "updating": "Aggiornamento...",
28 | "ready_to_play": "Gioca",
29 | "select_game_dir": "Seleziona la cartella di Titanfall 2"
30 | },
31 | "ea_app_running": "EA App sta andando:"
32 | },
33 | "mods": {
34 | "local": {
35 | "no_mods": "Nessuna mod è stata trovata.",
36 | "delete_confirm": "Sei sicuro di voler eliminare questa mod?",
37 | "part_of_ts_mod": "Questa Northstar mod è parte di una Thunderstore mod",
38 | "success_deleting": "{modName} Eliminata con successo",
39 | "delete": "Elimina"
40 | },
41 | "online": {
42 | "no_match": "Nessuna mod corrispondente trovata.",
43 | "try_another_search": "Prova un'altra ricerca!"
44 | },
45 | "menu": {
46 | "local": "Locale",
47 | "filter": "Filtra",
48 | "online": "Online",
49 | "search": "Cerca",
50 | "sort_mods": "Sorteggia mods",
51 | "select_categories": "Seleziona categorie",
52 | "sort": {
53 | "name_asc": "Per nome (da A alla Z)",
54 | "name_desc": "Per nome (da Z alla A)",
55 | "date_asc": "Per data (dal più vecchio)",
56 | "date_desc": "Per data (dal più recente)",
57 | "most_downloaded": "Più scaricate",
58 | "top_rated": "Più votate"
59 | }
60 | },
61 | "card": {
62 | "button": {
63 | "being_updated": "Aggiornando...",
64 | "installed": "Installato",
65 | "being_installed": "Installando...",
66 | "install": "Installa",
67 | "outdated": "Aggiorna"
68 | },
69 | "by": "per",
70 | "more_info": "Più informazioni",
71 | "remove": "Rimuovi mod",
72 | "remove_dialog_title": "Attenzione",
73 | "remove_dialog_text": "Eliminare Thunderstore mod?",
74 | "remove_success": "{modName} Rimossa",
75 | "install_success": "{modName} Installata"
76 | }
77 | },
78 | "menu": {
79 | "mods": "Mods",
80 | "settings": "Impostazioni",
81 | "dev": "Dev",
82 | "play": "Gioca",
83 | "changelog": "Note"
84 | },
85 | "notification": {
86 | "game_folder": {
87 | "wrong": {
88 | "title": "Cartella errata",
89 | "text": "La cartella selezionata non ha un'installazione di Titanfall2 valida."
90 | },
91 | "new": {
92 | "title": "Nuova cartella di gioco",
93 | "text": "Cartella di gioco aggiornata con successo."
94 | },
95 | "not_found": {
96 | "title": "Titanfall2 non trovato!",
97 | "text": "Per favore selezionare manualmente la posizione dell'installazione"
98 | }
99 | },
100 | "flightcore_outdated": {
101 | "title": "FlightCore fuori data!",
102 | "text": "Per favore aggiorna FlightCore.\nVersione in uso {oldVersion} fuori data.\nLa più recente è {newVersion}!"
103 | },
104 | "no_new": {
105 | "text": "Niente da vedere qui!",
106 | "title": "Aggiornato"
107 | },
108 | "profile": {
109 | "invalid": {
110 | "text": "Il profilo a cui hai provato ad accedere non è più valido.",
111 | "title": "Profilo non valido"
112 | }
113 | }
114 | },
115 | "settings": {
116 | "manage_install": "Gestisci l'installazione",
117 | "choose_folder": "Scegli la cartella dell'installazione",
118 | "open_game_folder": "Apri Cartella",
119 | "nb_ts_mods_per_page": "Numero di Thunderstore mods per pagina",
120 | "nb_ts_mods_per_page_desc1": "Questo ha un impatto sulle performazioni schermo mentre si navigano le Thunderstore mods.",
121 | "nb_ts_mods_per_page_desc2": "Cambiare questo valore a 0 per disattivare la paginazione.",
122 | "nb_ts_mods_reset": "Resetta a default",
123 | "language": "Lingua",
124 | "language_select": "Seleziona la tua lingua preferito",
125 | "about": "Al riguardo:",
126 | "flightcore_version": "Versione FlighCore:",
127 | "testing": "Testando:",
128 | "enable_test_channels": "Abilita i canali del test di rilascio",
129 | "dev_mode_enabled_title": "Attenzione!",
130 | "dev_mode_enabled_text": "Modalità Sviluppatore attivata.",
131 | "repair": {
132 | "title": "Ripara",
133 | "open_window": "Apri finestra di riparazione",
134 | "window": {
135 | "title": "Finestra riparazione di FlightCore",
136 | "warning": "Questa finestra contiene varie funzionalità per riparare problemi comuni con Northstar e FlightCore.",
137 | "disable_all_but_core": "Disattiva tutte le mods (eccetto quelle di Northstar)",
138 | "disable_all_but_core_success": "Disattivate tutte le mods (eccetto quelle di Northstar)",
139 | "force_reinstall_ns": "Forza reinstallazione di Northstar",
140 | "force_delete_temp_dl": "Forza l'eliminazione della cartella dei download temporanei",
141 | "delete_persistent_store": "Elimina lo spazio d'archiviazione persistente di FlightCore",
142 | "reinstall_title": "Reinstallando Northstar forzatamente",
143 | "reinstall_text": "Attendere per favore",
144 | "reinstall_success": "Northstar reinstallato con successo",
145 | "kill_northstar_process": "Ferma il processo Northstar/Titanfall2 in esecuzione",
146 | "disable_modsettings_success": "ModSettings disabilitata",
147 | "disable_modsettings": "Disabilita la mod ModSettings"
148 | }
149 | },
150 | "profile": {
151 | "active": "Profilo attivo",
152 | "dialog": {
153 | "clone": "Clona",
154 | "delete": "Elimina",
155 | "delete_confirm": "Sei sicuro di voler eliminare questo profilo?",
156 | "title": "Profili"
157 | },
158 | "edit": "Modifica profilo"
159 | },
160 | "show_deprecated_mods": "Mostra mod di Thunderstore deprecate",
161 | "show_deprecated_mods_desc2": "Fai attenzione, alcune mod di solito sono deprecate per un buon motivo.",
162 | "show_deprecated_mods_desc1": "Permette di vedere le mod deprecate nella collezione online."
163 | },
164 | "channels": {
165 | "release": {
166 | "switch": {
167 | "text": "Cambiato il canale di rilascio a \"{canal}\"."
168 | }
169 | },
170 | "names": {
171 | "Northstar": "Northstar",
172 | "NorthstarReleaseCandidate": "Northstar versione pre-rilascio"
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "changelog": "Dziennik zmian",
4 | "mods": "Mody",
5 | "settings": "Ustawienia",
6 | "dev": "Dev",
7 | "play": "Graj"
8 | },
9 | "generic": {
10 | "yes": "Tak",
11 | "no": "Nie",
12 | "error": "Błąd",
13 | "cancel": "Anuluj",
14 | "downloading": "Pobieranie",
15 | "extracting": "Wypakowywanie",
16 | "done": "Gotowe",
17 | "success": "Sukces",
18 | "informationShort": "Informacja",
19 | "confirm": "Potwierdź"
20 | },
21 | "play": {
22 | "button": {
23 | "northstar_is_running": "Gra jest uruchomiona",
24 | "select_game_dir": "Wybierz folder gry Titanfall2",
25 | "install": "Zainstaluj",
26 | "update": "Aktualizuj",
27 | "updating": "Aktualizowanie...",
28 | "ready_to_play": "Uruchom grę",
29 | "installing": "Instalowanie..."
30 | },
31 | "unknown_version": "Nieznana wersja",
32 | "see_patch_notes": "zobacz listę zmian",
33 | "players": "gracze",
34 | "servers": "serwery",
35 | "northstar_running": "Northstar jest uruchomiony:",
36 | "ea_app_running": "EA App jest uruchomiony:",
37 | "unable_to_load_playercount": "Nie można załadować liczby graczy"
38 | },
39 | "mods": {
40 | "local": {
41 | "no_mods": "Nie znaleziono żadnych modów.",
42 | "delete_confirm": "Czy na pewno chcesz usunąć ten mod?",
43 | "delete": "Usuń",
44 | "success_deleting": "Sukces usuwania {modName}",
45 | "part_of_ts_mod": "Ten mod Northstar jest częścią moda Thunderstore"
46 | },
47 | "online": {
48 | "no_match": "Nie znaleziono pasującego moda.",
49 | "try_another_search": "Spróbuj innego wyszukiwania!"
50 | },
51 | "menu": {
52 | "local": "Lokalne",
53 | "online": "Online",
54 | "filter": "Filtry",
55 | "search": "Szukaj",
56 | "sort_mods": "Sortowanie modów",
57 | "select_categories": "Wybierz kategorie",
58 | "sort": {
59 | "name_asc": "Według nazwy (od A do Z)",
60 | "name_desc": "Według nazwy (od Z do A)",
61 | "date_desc": "Według daty (od najnowszej)",
62 | "most_downloaded": "Najczęściej pobierane",
63 | "top_rated": "Najwyżej ocenione",
64 | "date_asc": "Według daty (od najstarszej)"
65 | }
66 | },
67 | "card": {
68 | "button": {
69 | "being_installed": "Instalowanie...",
70 | "being_updated": "Aktualizowanie...",
71 | "installed": "Zainstalowano",
72 | "install": "Zainstaluj",
73 | "outdated": "Aktualizuj"
74 | },
75 | "by": "od",
76 | "more_info": "Więcej informacji",
77 | "remove": "Usuń moda",
78 | "remove_dialog_title": "Ostrzeżenie",
79 | "remove_dialog_text": "Usunąć mod Thunderstore?",
80 | "remove_success": "Usunięto {modName}",
81 | "install_success": "Zainstalowano {modName}"
82 | }
83 | },
84 | "settings": {
85 | "manage_install": "Zarządzaj instalacją",
86 | "choose_folder": "Wybierz folder instalacyjny",
87 | "nb_ts_mods_per_page": "Liczba modów Thunderstore na stronie",
88 | "nb_ts_mods_per_page_desc2": "Ustaw tę wartość na 0, aby wyłączyć paginację.",
89 | "nb_ts_mods_reset": "Przywrócenie ustawień domyślnych",
90 | "language": "Język",
91 | "language_select": "Wybierz swój ulubiony język",
92 | "about": "O:",
93 | "flightcore_version": "Wersja FlightCore:",
94 | "testing": "Testy:",
95 | "enable_test_channels": "Włączenie kanałów wydań testowych",
96 | "dev_mode_enabled_title": "Uważaj!",
97 | "dev_mode_enabled_text": "Tryb deweloperski włączony.",
98 | "repair": {
99 | "title": "Naprawa",
100 | "open_window": "Otwórz okno naprawy",
101 | "window": {
102 | "disable_all_but_core": "Wyłączenie wszystkich modów poza podstawowymi",
103 | "disable_all_but_core_success": "Wyłączone wszystkie mody oprócz podstawowych",
104 | "force_reinstall_ns": "Wymuś reinstalację Northstara",
105 | "force_delete_temp_dl": "Wymuś usunięcie folderu tymczasowego pobierania",
106 | "delete_persistent_store": "Usuń stały magazyn FlightCore",
107 | "reinstall_title": "Wymuszona reinstalacja Northstara",
108 | "reinstall_text": "Proszę czekać",
109 | "reinstall_success": "Pomyślnie przeinstalowano Northstar",
110 | "title": "Okno naprawy FlightCore",
111 | "warning": "To okno zawiera różne funkcje do naprawy typowych problemów z Northstar i FlightCore.",
112 | "disable_modsettings": "Wyłącz moda ModSettings",
113 | "disable_modsettings_success": "Wyłączono moda ModSettings",
114 | "kill_northstar_process": "Zamknij uruchomiony proces Northstar/Titanfall2"
115 | }
116 | },
117 | "nb_ts_mods_per_page_desc1": "Ma to wpływ na wydajność wyświetlania podczas przeglądania modów Thunderstore.",
118 | "open_game_folder": "Otwórz folder",
119 | "show_deprecated_mods_desc2": "Ostrożnie, mody są zazwyczaj oznaczone jako przestarzałe nie bez powodu.",
120 | "show_deprecated_mods": "Pokaż przestarzałe mody Thunderstore",
121 | "show_deprecated_mods_desc1": "Pozwala to zobaczyć przestarzałe mody w kolekcji modów online.",
122 | "profile": {
123 | "active": "Aktywny profil",
124 | "dialog": {
125 | "title": "Profile",
126 | "delete": "Usuń",
127 | "clone": "Klonuj",
128 | "new_profile_name": "Wprowadź nową nazwę profilu",
129 | "create_empty": "Nowy profil",
130 | "delete_confirm": "Czy na pewno chcesz usunąć ten profil?"
131 | },
132 | "edit": "Edytuj profile"
133 | }
134 | },
135 | "notification": {
136 | "game_folder": {
137 | "new": {
138 | "title": "Nowy folder z grą",
139 | "text": "Folder gry został pomyślnie zaktualizowany."
140 | },
141 | "wrong": {
142 | "title": "Niewłaściwy folder",
143 | "text": "Wybrany folder nie jest poprawną instalacją Titanfall2."
144 | },
145 | "not_found": {
146 | "title": "Nie znaleziono Titanfall2!",
147 | "text": "Proszę ręcznie wybrać lokalizację instalacji"
148 | }
149 | },
150 | "flightcore_outdated": {
151 | "title": "FlightCore nieaktualny!",
152 | "text": "Proszę zaktualizować FlightCore.\nUruchomiono przestarzałą wersję {oldVersion}.\nNajnowsza to {newVersion}!"
153 | },
154 | "profile": {
155 | "invalid": {
156 | "title": "Nieprawidłowy profil",
157 | "text": "Profil, na który próbowano się przełączyć, nie jest już prawidłowy."
158 | }
159 | },
160 | "no_new": {
161 | "title": "Aktualny",
162 | "text": "Nie ma tu nic do obejrzenia!"
163 | },
164 | "date_prefix": "na"
165 | },
166 | "channels": {
167 | "release": {
168 | "switch": {
169 | "text": "Przełączono kanał wydań na \"{canal}\"."
170 | }
171 | },
172 | "names": {
173 | "Northstar": "Northstar",
174 | "NorthstarReleaseCandidate": "Kandydat do wydania Northstar"
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "generic": {
3 | "yes": "Да",
4 | "no": "Нет",
5 | "extracting": "Распаковывание",
6 | "done": "Готово",
7 | "success": "Успешно",
8 | "error": "Ошибка",
9 | "cancel": "Отмена",
10 | "informationShort": "Информация",
11 | "downloading": "Скачивание",
12 | "confirm": "Подтвердить"
13 | },
14 | "menu": {
15 | "mods": "Моды",
16 | "play": "Играть",
17 | "settings": "Настройки",
18 | "dev": "Разработчик",
19 | "changelog": "Обновления"
20 | },
21 | "play": {
22 | "button": {
23 | "northstar_is_running": "Игра запущена",
24 | "install": "Установить",
25 | "installing": "Установка...",
26 | "updating": "Обновление...",
27 | "ready_to_play": "Запустить игру",
28 | "update": "Обновить",
29 | "select_game_dir": "Выберите папку с Titanfall 2"
30 | },
31 | "unknown_version": "Неизвестная версия",
32 | "players": "игроков",
33 | "servers": "серверов",
34 | "unable_to_load_playercount": "Не можем загрузить количество игроков",
35 | "northstar_running": "Northstar запущен:",
36 | "ea_app_running": "EA App запущен:",
37 | "see_patch_notes": "просмотреть список изменений"
38 | },
39 | "mods": {
40 | "local": {
41 | "delete_confirm": "Вы уверены, что хотите удалить этот мод?",
42 | "delete": "Удалить",
43 | "success_deleting": "{modName} Успешно удален",
44 | "no_mods": "Моды не найдены.",
45 | "part_of_ts_mod": "Этот мод Northstar является частью мода на Thunderstore"
46 | },
47 | "online": {
48 | "no_match": "Не найдено совпадающих модов.",
49 | "try_another_search": "Попробуйте другой запрос!"
50 | },
51 | "menu": {
52 | "online": "Онлайн",
53 | "filter": "Фильтр",
54 | "search": "Поиск",
55 | "sort_mods": "Сортировать моды",
56 | "sort": {
57 | "name_asc": "По имени (от A до Z)",
58 | "name_desc": "По имени (от Z до A)",
59 | "date_asc": "По дате (со старейшего)",
60 | "date_desc": "По дате (с новейшего)",
61 | "top_rated": "Самый популярный",
62 | "most_downloaded": "Самый загружаемый"
63 | },
64 | "local": "Установленные",
65 | "select_categories": "Выбрать категории"
66 | },
67 | "card": {
68 | "button": {
69 | "being_installed": "Установка...",
70 | "being_updated": "Обновление...",
71 | "installed": "Установлен",
72 | "install": "Установить",
73 | "outdated": "Обновить"
74 | },
75 | "by": "от",
76 | "remove": "Удалить мод",
77 | "remove_dialog_title": "Внимание",
78 | "remove_dialog_text": "Удалить мод Thunderstore?",
79 | "remove_success": "{modName} Удален",
80 | "more_info": "Подробнее",
81 | "install_success": "{modName} Установлен"
82 | }
83 | },
84 | "settings": {
85 | "manage_install": "Управлять установкой",
86 | "choose_folder": "Выберите папку установки",
87 | "open_game_folder": "Открыть папку",
88 | "nb_ts_mods_reset": "Вернуть по умолчанию",
89 | "language": "Язык",
90 | "language_select": "Выберите свой любимый язык",
91 | "testing": "Тестирование:",
92 | "enable_test_channels": "Включить каналы с тестовыми релизами",
93 | "dev_mode_enabled_title": "Осторожно!",
94 | "repair": {
95 | "open_window": "Открыть окно фиксов",
96 | "window": {
97 | "title": "Окно фиксов FlightCore",
98 | "force_reinstall_ns": "Принудительно переустановить Northstar",
99 | "delete_persistent_store": "Удалить постоянное хранилище FlightCore",
100 | "reinstall_title": "Принудительно переустанавливаем Northstar",
101 | "reinstall_text": "Пожалуйста, подождите",
102 | "disable_all_but_core_success": "Выключены все моды кроме главных",
103 | "disable_all_but_core": "Выключить все моды, кроме главных",
104 | "warning": "Это окно содержит различные функции для устранения часто возникающих проблем с Northstar и FlightCore.",
105 | "force_delete_temp_dl": "Принудительно удалить папку с временными загрузками",
106 | "reinstall_success": "Northstar успешно переустановлен",
107 | "disable_modsettings": "Выключить мод ModSettings",
108 | "disable_modsettings_success": "Выключен мод ModSettings",
109 | "kill_northstar_process": "Закрыть запущенный Northstar/Titanfall 2"
110 | },
111 | "title": "Фиксы"
112 | },
113 | "nb_ts_mods_per_page_desc1": "Это влияет на производительность при просмотре модов с Thunderstore.",
114 | "about": "Информация:",
115 | "nb_ts_mods_per_page": "Количество модов Thunderstore на каждую страницу",
116 | "nb_ts_mods_per_page_desc2": "Установите это значение на 0, чтобы отключить страницы.",
117 | "flightcore_version": "Версия FlightCore:",
118 | "dev_mode_enabled_text": "Включен режим разработчика.",
119 | "show_deprecated_mods": "Показать устаревшие моды Thunderstore",
120 | "show_deprecated_mods_desc1": "Это позволяет вам видеть устаревшие моды в меню онлайн модов.",
121 | "show_deprecated_mods_desc2": "Внимание, такие моды обычно устаревшие по хорошей причине.",
122 | "profile": {
123 | "active": "Активный Профиль",
124 | "edit": "Редактировать Профили",
125 | "dialog": {
126 | "title": "Профили",
127 | "clone": "Копировать",
128 | "delete": "Удалить",
129 | "delete_confirm": "Вы уверены, что хотите удалить этот профиль?",
130 | "new_profile_name": "Введите новое имя профиля",
131 | "create_empty": "Новый профиль"
132 | }
133 | },
134 | "show_nsfw_mods": "Показывать NSFW-моды с Thunderstore"
135 | },
136 | "notification": {
137 | "game_folder": {
138 | "new": {
139 | "title": "Новая папка игры",
140 | "text": "Папка игры успешно обновлена."
141 | },
142 | "wrong": {
143 | "title": "Неправильная папка",
144 | "text": "Выбранная папка не является папкой с Titanfall 2."
145 | },
146 | "not_found": {
147 | "title": "Titanfall 2 не найден!",
148 | "text": "Пожалуйста, вручную выберите место установки"
149 | }
150 | },
151 | "flightcore_outdated": {
152 | "title": "FlightCore устарел!",
153 | "text": "Пожалуйста, обновите FlightCore\nСейчас запущена старая версия - {oldVersion}.\nНовейшая версия - {newVersion}!"
154 | },
155 | "profile": {
156 | "invalid": {
157 | "title": "Некорректный Профиль",
158 | "text": "Профиль, на который вы пытаетесь переключиться, больше не является корректным."
159 | }
160 | },
161 | "no_new": {
162 | "text": "Смотреть здесь нечего!",
163 | "title": "Нет уведомлений"
164 | },
165 | "date_prefix": "в"
166 | },
167 | "channels": {
168 | "release": {
169 | "switch": {
170 | "text": "Релизный канал переключен на \"{canal}\"."
171 | }
172 | },
173 | "names": {
174 | "Northstar": "Northstar",
175 | "NorthstarReleaseCandidate": "Пре-релизная версия Northstar"
176 | }
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/src-vue/src/i18n/lang/zh_Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "menu": {
3 | "mods": "模组",
4 | "settings": "设置",
5 | "dev": "开发者模式",
6 | "play": "开始游玩",
7 | "changelog": "更新日志"
8 | },
9 | "generic": {
10 | "error": "错误",
11 | "cancel": "取消",
12 | "yes": "是",
13 | "no": "否",
14 | "informationShort": "信息",
15 | "downloading": "下载中",
16 | "extracting": "解压中",
17 | "done": "完成",
18 | "success": "成功",
19 | "confirm": "确认"
20 | },
21 | "play": {
22 | "button": {
23 | "northstar_is_running": "游戏正在运行",
24 | "select_game_dir": "选择Titanfall 2游戏目录",
25 | "install": "安装",
26 | "installing": "安装中...",
27 | "update": "升级",
28 | "ready_to_play": "启动游戏",
29 | "updating": "升级中..."
30 | },
31 | "unknown_version": "未知版本",
32 | "see_patch_notes": "参阅相关补丁说明",
33 | "servers": "服务器",
34 | "players": "玩家",
35 | "unable_to_load_playercount": "加载玩家数量失败",
36 | "ea_app_running": "EA App运行状态:",
37 | "northstar_running": "Northstar运行状态:"
38 | },
39 | "mods": {
40 | "local": {
41 | "no_mods": "未找到模组。",
42 | "delete_confirm": "你确定要删除该模组吗?",
43 | "delete": "删除",
44 | "part_of_ts_mod": "该Northstar模组来源于Thunderstore",
45 | "success_deleting": "成功删除 {modName}"
46 | },
47 | "online": {
48 | "try_another_search": "尝试其他搜索方式!",
49 | "no_match": "未找到相匹配的模组。"
50 | },
51 | "menu": {
52 | "local": "本地",
53 | "search": "搜索",
54 | "sort_mods": "模组排序",
55 | "select_categories": "标签选择",
56 | "sort": {
57 | "date_desc": "日期降序",
58 | "date_asc": "日期升序",
59 | "name_desc": "按名称(Z到A)",
60 | "most_downloaded": "最多下载",
61 | "top_rated": "最高评分",
62 | "name_asc": "按名称(A到Z)"
63 | },
64 | "online": "线上",
65 | "filter": "筛选"
66 | },
67 | "card": {
68 | "button": {
69 | "being_installed": "安装中...",
70 | "being_updated": "升级中...",
71 | "installed": "已安装",
72 | "install": "安装",
73 | "outdated": "升级"
74 | },
75 | "by": "作者:",
76 | "remove": "移除模组",
77 | "remove_dialog_title": "警告",
78 | "remove_success": "已移除{modName}",
79 | "install_success": "已安装 {modName}",
80 | "more_info": "更多信息",
81 | "remove_dialog_text": "删除该来自Thunderstore的模组?"
82 | }
83 | },
84 | "settings": {
85 | "manage_install": "安装管理",
86 | "choose_folder": "选择安装目录",
87 | "open_game_folder": "打开文件夹",
88 | "nb_ts_mods_per_page": "Thunderstore每页显示多少个模组",
89 | "nb_ts_mods_per_page_desc2": "该值设为0时将不再显示页码。",
90 | "nb_ts_mods_reset": "重置为默认值",
91 | "language": "语言",
92 | "language_select": "请选择你需要的语言",
93 | "about": "关于:",
94 | "flightcore_version": "FlightCore 版本:",
95 | "testing": "测试选项:",
96 | "enable_test_channels": "开启测试版本选项",
97 | "nb_ts_mods_per_page_desc1": "该数值对加载Thunderstore页面时的速度有影响。",
98 | "dev_mode_enabled_title": "看上面!",
99 | "dev_mode_enabled_text": "开发者模式已启用。",
100 | "show_deprecated_mods": "显示已弃用的Thunderstore模组",
101 | "show_deprecated_mods_desc1": "该选项会使您可以在线上模组合集中看到已弃用的模组。",
102 | "show_deprecated_mods_desc2": "请注意,这类模组被弃用一般是有原因的。",
103 | "repair": {
104 | "title": "修复",
105 | "window": {
106 | "title": "FlightCore 修复工具",
107 | "warning": "此工具包含修复Northstar和FlightCore各种常见问题的功能。",
108 | "disable_all_but_core": "除了核心模组以外禁用其他模组",
109 | "disable_all_but_core_success": "已禁用除核心模组以外的所有模组",
110 | "disable_modsettings": "禁用ModSettings模组",
111 | "disable_modsettings_success": "已禁用ModSettings模组",
112 | "force_delete_temp_dl": "强制删除临时下载目录",
113 | "delete_persistent_store": "删除FlightCore永久存储文件",
114 | "reinstall_text": "请耐心等待",
115 | "reinstall_success": "成功重装Northstar",
116 | "force_reinstall_ns": "强制重装Northstar",
117 | "reinstall_title": "正在强制重装Northstar",
118 | "kill_northstar_process": "终止正在运行的 Northstar/Titanfall2 进程"
119 | },
120 | "open_window": "打开修复工具"
121 | },
122 | "profile": {
123 | "active": "当前用户配置",
124 | "edit": "编辑用户配置",
125 | "dialog": {
126 | "title": "用户配置",
127 | "delete_confirm": "你确定要删除此配置文件吗?",
128 | "delete": "删除"
129 | }
130 | }
131 | },
132 | "notification": {
133 | "game_folder": {
134 | "new": {
135 | "title": "新的游戏目录",
136 | "text": "已成功更新游戏目录。"
137 | },
138 | "wrong": {
139 | "title": "错误的文件夹",
140 | "text": "所选文件夹不是有效的Titanfall2安装目录。"
141 | },
142 | "not_found": {
143 | "title": "未找到Titanfall2!",
144 | "text": "请手动选择安装目录"
145 | }
146 | },
147 | "flightcore_outdated": {
148 | "title": "FlightCore需要更新!",
149 | "text": "请更新FlightCore.\n正在运行旧版本 {oldVersion}.\n最新版本为 {newVersion}!"
150 | },
151 | "profile": {
152 | "invalid": {
153 | "title": "无效用户配置",
154 | "text": "您尝试切换到的用户配置已失效。"
155 | }
156 | }
157 | },
158 | "channels": {
159 | "release": {
160 | "switch": {
161 | "text": "将资源版本切换至 \"{canal}\"."
162 | }
163 | },
164 | "names": {
165 | "NorthstarReleaseCandidate": "Northstar测试版本",
166 | "Northstar": "Northstar"
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src-vue/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import { createI18n } from "vue-i18n";
3 | import App from './App.vue'
4 | import ElementPlus from "element-plus";
5 | import * as ElementPlusIconsVue from '@element-plus/icons-vue'
6 | import { store } from './plugins/store';
7 | import PlayView from "./views/PlayView.vue";
8 | import ChangelogView from "./views/ChangelogView.vue";
9 | import ModsView from "./views/ModsView.vue";
10 | import SettingsView from "./views/SettingsView.vue";
11 | import DeveloperView from "./views/DeveloperView.vue";
12 | import RepairView from "./views/RepairView.vue";
13 | import {createRouter, createWebHashHistory} from "vue-router";
14 | import en from "./i18n/lang/en.json";
15 | import fr from "./i18n/lang/fr.json";
16 | import da from "./i18n/lang/da.json";
17 | import de from "./i18n/lang/de.json";
18 | import es from "./i18n/lang/es.json";
19 | import pl from "./i18n/lang/pl.json";
20 | import ru from "./i18n/lang/ru.json";
21 | import it from "./i18n/lang/it.json";
22 | import zh_Hans from "./i18n/lang/zh_Hans.json";
23 |
24 |
25 | const app = createApp(App);
26 |
27 | // internationalization
28 | export const i18n = createI18n({
29 | locale: 'en',
30 | fallbackLocale: 'en',
31 | messages: {
32 | en, fr, da, de, es, pl, ru, it, zh_Hans
33 | }
34 | });
35 | app.use(i18n);
36 |
37 | // styles
38 | import 'element-plus/theme-chalk/index.css';
39 | import './style.css'
40 |
41 | app.use(ElementPlus);
42 |
43 | // icons
44 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
45 | app.component(key, component);
46 | }
47 |
48 | // style
49 | app.use( store, '$store' );
50 |
51 |
52 | // routes
53 | const routes = [
54 | { path: '/', name: 'Main', component: async () => PlayView},
55 | { path: '/changelog', name: 'Changelog', component: async () => ChangelogView},
56 | { path: '/mods', name: 'Mods', component: async () => ModsView},
57 | { path: '/settings', name: 'Settings', component: async () => SettingsView},
58 | { path: '/dev', name: 'Dev', component: async () => DeveloperView},
59 | { path: '/repair', name: 'Repair', component: async () => RepairView},
60 | ];
61 | export const router = createRouter({
62 | history: createWebHashHistory(),
63 | routes, // short for `routes: routes`
64 | });
65 | app.use(router);
66 |
67 |
68 | app.mount('#app')
69 |
--------------------------------------------------------------------------------
/src-vue/src/plugins/modules/notifications.ts:
--------------------------------------------------------------------------------
1 | type NotificationType = 'success' | 'warning' | 'info' | 'error';
2 |
3 | export interface Notification {
4 | title: string;
5 | text: string;
6 | type: NotificationType;
7 | }
8 |
9 | interface NotificationsStoreState {
10 | notifications: Notification[];
11 | }
12 |
13 |
14 | /**
15 | * This notification module is meant to host the list of notifications that have been fired while the application was
16 | * not focused.
17 | * This list is then used by the [NotificationButton] component to display notifications to user.
18 | **/
19 | export const notificationsModule = {
20 | state: () => ({
21 | notifications: []
22 | }) as NotificationsStoreState,
23 | mutations: {
24 | addNotification(state: NotificationsStoreState, payload: Notification) {
25 | state.notifications.push(payload);
26 | },
27 | removeNotification(state: NotificationsStoreState, index: number): void {
28 | state.notifications.splice(index, 1);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src-vue/src/plugins/modules/pull_requests.ts:
--------------------------------------------------------------------------------
1 | import { invoke } from "@tauri-apps/api/core";
2 | import { open } from '@tauri-apps/plugin-shell';
3 | import { PullsApiResponseElement } from "../../../../src-tauri/bindings/PullsApiResponseElement";
4 | import { PullRequestType } from '../../../../src-tauri/bindings/PullRequestType';
5 | import { store } from "../store";
6 | import { showErrorNotification, showNotification } from "../../utils/ui";
7 |
8 | interface PullRequestStoreState {
9 | searchValue: string,
10 | pull_requests_launcher: PullsApiResponseElement[],
11 | pull_requests_mods: PullsApiResponseElement[],
12 | }
13 |
14 | export const pullRequestModule = {
15 | state: () => ({
16 | pull_requests_launcher: [],
17 | pull_requests_mods: [],
18 | }),
19 | mutations: {
20 | async getPullRequests(state: PullRequestStoreState, pull_request_type: PullRequestType) {
21 | await invoke("get_pull_requests_wrapper", { installType: pull_request_type })
22 | .then((message) => {
23 | switch (pull_request_type) {
24 | case "Mods":
25 | state.pull_requests_mods = message;
26 | break;
27 |
28 | case "Launcher":
29 | state.pull_requests_launcher = message;
30 | break;
31 |
32 | default:
33 | console.error("We should never end up here");
34 | }
35 | })
36 | .catch((error) => {
37 | showErrorNotification(error);
38 | });
39 | },
40 | async downloadLauncherPR(_state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
41 | await invoke("get_launcher_download_link", { commitSha: pull_request.head.sha })
42 | .then((url) => {
43 | // Open URL in default HTTPS handler (i.e. default browser)
44 | open(url);
45 | })
46 | .catch((error) => {
47 | showErrorNotification(error);
48 | });
49 | },
50 | async downloadModsPR(_state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
51 | let url = `https://github.com/${pull_request.head.repo.full_name}/archive/refs/heads/${pull_request.head.ref}.zip`
52 | open(url);
53 | },
54 | async installLauncherPR(_state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
55 | // Send notification telling the user to wait for the process to finish
56 | const notification = showNotification(`Installing launcher PR ${pull_request.number}`, 'Please wait', 'info', 0);
57 |
58 | await invoke("apply_launcher_pr", { pullRequest: pull_request, gameInstall: store.state.game_install })
59 | .then((message) => {
60 | console.log(message);
61 | // Show user notification if mod install completed.
62 | showNotification(`Done`, `Installed ${pull_request.number}: "${pull_request.title}"`);
63 | })
64 | .catch((error) => {
65 | showErrorNotification(error);
66 | })
67 | .finally(() => {
68 | // Clear old notification
69 | notification.close();
70 | });
71 | },
72 | async installModsPR(_state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
73 | // Send notification telling the user to wait for the process to finish
74 | const notification = showNotification(`Installing mods PR ${pull_request.number}`, 'Please wait', 'info', 0);
75 |
76 | await invoke("apply_mods_pr", { pullRequest: pull_request, gameInstall: store.state.game_install })
77 | .then((_message) => {
78 | // Show user notification if mod install completed.
79 | showNotification(
80 | `Done`,
81 | `Installed ${pull_request.number}: "${pull_request.title}"\nMake sure to launch via batch file or by specifying correct profile!`,
82 | 'success',
83 | 7000
84 | );
85 | })
86 | .catch((error) => {
87 | showErrorNotification(error);
88 | })
89 | .finally(() => {
90 | // Clear old notification
91 | notification.close();
92 | });
93 | },
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src-vue/src/plugins/modules/search.ts:
--------------------------------------------------------------------------------
1 | interface SearchStoreState {
2 | searchValue: string
3 | }
4 |
5 | export const searchModule = {
6 | state: () => ({
7 | // This is the treated value of search input
8 | searchValue: '',
9 | // Selected mod categories
10 | selectedCategories: [],
11 | showDeprecatedMods: false,
12 | showNsfwMods: false,
13 | sortValue: {label: '', value: ''}
14 | }),
15 | getters: {
16 | searchWords(state: SearchStoreState): string {
17 | return state.searchValue.toLowerCase();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src-vue/src/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html, body {
6 | height: 100%;
7 | width: 100%;
8 | }
9 |
10 | body {
11 | margin: 0;
12 | font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
13 | --fc-menu_height: 50px;
14 | user-select: none;
15 | }
16 |
17 | #app {
18 | position: relative;
19 | height: 100%;
20 | width: 100%;
21 | }
22 |
23 | #fc_bg__container {
24 | background: url(/src/assets/1009235.jpg) center no-repeat;
25 | background-size: cover;
26 | height: 100%;
27 | width: 100%;
28 | position: fixed;
29 | filter: brightness(0.8);
30 | scale: 1.03;
31 | }
32 |
33 | .el-scrollbar {
34 | --el-scrollbar-opacity: 0.5;
35 | --el-scrollbar-hover-opacity: 0.7;
36 | }
37 |
38 | .fc-container {
39 | position: relative;
40 | padding-top: var(--fc-menu_height);
41 | height: 100%;
42 | color: white;
43 | }
44 |
45 | .noModMessage {
46 | color: white;
47 | margin: 30px 15px;
48 | }
49 |
50 | .fc_popper {
51 | width: auto !important;
52 | }
53 |
54 | .el-popconfirm {
55 | word-break: break-word;
56 | }
57 |
--------------------------------------------------------------------------------
/src-vue/src/utils/GameInstall.ts:
--------------------------------------------------------------------------------
1 | export interface GameInstall {
2 | game_path: string;
3 | profile: string,
4 | install_type: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src-vue/src/utils/NorthstarState.ts:
--------------------------------------------------------------------------------
1 | export enum NorthstarState {
2 | GAME_NOT_FOUND = "GAME_NOT_FOUND",
3 | INSTALL = "INSTALL",
4 | INSTALLING = "INSTALLING",
5 | MUST_UPDATE = "MUST_UPDATE",
6 | UPDATING = "UPDATING",
7 | READY_TO_PLAY = "READY_TO_PLAY"
8 | }
--------------------------------------------------------------------------------
/src-vue/src/utils/ReleaseCanal.ts:
--------------------------------------------------------------------------------
1 | export enum ReleaseCanal {
2 | RELEASE = 'Northstar',
3 | RELEASE_CANDIDATE = 'NorthstarReleaseCandidate'
4 | }
5 |
--------------------------------------------------------------------------------
/src-vue/src/utils/SortOptions.d.ts:
--------------------------------------------------------------------------------
1 | export enum SortOptions {
2 | NAME_ASC = 'name_asc',
3 | NAME_DESC = 'name_desc',
4 | DATE_ASC = 'date_asc',
5 | DATE_DESC = 'date_desc',
6 | MOST_DOWNLOADED = 'most_downloaded',
7 | TOP_RATED = 'top_rated'
8 | }
9 |
--------------------------------------------------------------------------------
/src-vue/src/utils/Tabs.ts:
--------------------------------------------------------------------------------
1 | export enum Tabs {
2 | PLAY = '/',
3 | CHANGELOG = '/changelog',
4 | SETTINGS = '/settings',
5 | DEV = '/dev',
6 | MODS = '/mods',
7 | REPAIR = '/repair',
8 | }
9 |
--------------------------------------------------------------------------------
/src-vue/src/utils/filter.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Implements a fuzzy filter
3 | * Iterates through chars of `search_term` and checks if each char exists in consecutive order in `text`.
4 | * For example, this means that `text="Gecko"` and `search_term="geo"` will return `true`
5 | * but using `text="Gecko"` and `search_term="goe"` will return `false`
6 | *
7 | * Implements a subset of "fuzzy string searching"
8 | * https://en.wikipedia.org/wiki/Approximate_string_matching
9 | */
10 | function fuzzy_filter(text: string, search_term: string): boolean {
11 | const lowercase_text = text.toLowerCase();
12 | const lowercase_search_term = search_term.toLowerCase();
13 |
14 | let previousIndex = -1;
15 | for (let i = 0; i < lowercase_search_term.length; i++) {
16 | const char = lowercase_search_term[i];
17 | const currentIndex = lowercase_text.indexOf(char, previousIndex + 1);
18 | if (currentIndex === -1) {
19 | return false;
20 | }
21 | previousIndex = currentIndex;
22 | }
23 |
24 | return true;
25 | }
26 | export { fuzzy_filter };
27 |
--------------------------------------------------------------------------------
/src-vue/src/utils/thunderstore/ThunderstoreModStatus.ts:
--------------------------------------------------------------------------------
1 | export enum ThunderstoreModStatus {
2 | INSTALLED,
3 | BEING_INSTALLED,
4 | BEING_UPDATED,
5 | NOT_INSTALLED,
6 | OUTDATED
7 | }
8 |
--------------------------------------------------------------------------------
/src-vue/src/utils/thunderstore/version.ts:
--------------------------------------------------------------------------------
1 | import {ThunderstoreMod} from "../../../../src-tauri/bindings/ThunderstoreMod";
2 | import {NorthstarMod} from "../../../../src-tauri/bindings/NorthstarMod";
3 | import {store} from "../../plugins/store";
4 |
5 | /**
6 | * Strips off a Thunderstore dependency string from its version
7 | * (e.g. "taskinoz-WallrunningTitans-1.0.0" to
8 | * "taskinoz-WallrunningTitans").
9 | **/
10 | function getThunderstoreDependencyStringPrefix(dependency: string): string {
11 | const dependencyStringMembers = dependency.split('-');
12 | return `${dependencyStringMembers[0]}-${dependencyStringMembers[1]}`;
13 | }
14 |
15 | function isThunderstoreModOutdated(mod: ThunderstoreMod): boolean {
16 | // Ensure mod is up-to-date.
17 | const tsModPrefix = getThunderstoreDependencyStringPrefix(mod.versions[0].full_name);
18 | const matchingMods: NorthstarMod[] = store.state.installed_mods.filter((mod: NorthstarMod) => {
19 | if (!mod.thunderstore_mod_string) return false;
20 | return getThunderstoreDependencyStringPrefix(mod.thunderstore_mod_string!) === tsModPrefix;
21 | });
22 | if (matchingMods.length !== 0) {
23 | // There shouldn't be several mods with same dependency string, but we never know...
24 | const matchingMod = matchingMods[0];
25 | // A mod is outdated if its dependency strings differs from Thunderstore dependency string
26 | // (no need for semver check here).
27 | // This assumes mod versions list is sorted from newest to oldest version.
28 | return matchingMod.thunderstore_mod_string !== mod.versions[0].full_name;
29 | }
30 | return false;
31 | }
32 |
33 | export { isThunderstoreModOutdated };
34 |
--------------------------------------------------------------------------------
/src-vue/src/utils/ui.ts:
--------------------------------------------------------------------------------
1 | import { ElNotification, NotificationHandle } from "element-plus";
2 | import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window';
3 | import { i18n } from "../main";
4 | import { store } from "../plugins/store";
5 |
6 | /**
7 | * Displays content to the user in the form of a notification appearing on screen bottom right.
8 | * If the app is not focused when this is invoked, a notification is added to the notifications menu.
9 | **/
10 | function showNotification(
11 | title: string,
12 | message: string = '',
13 | type: 'success' | 'warning' | 'error' | 'info' = 'success',
14 | duration: number = 4500
15 | ): NotificationHandle {
16 | if (!document.hasFocus()) {
17 | const date = new Date();
18 | const titleWithDate = `${title} (${i18n.global.tc('notification.date_prefix')} ${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)})`;
19 | store.commit('addNotification', {title: titleWithDate, text: message, type});
20 | getCurrentWindow().requestUserAttention(UserAttentionType.Informational);
21 | }
22 |
23 | return ElNotification({
24 | title, message, type, duration,
25 | position: 'bottom-right',
26 | });
27 | }
28 |
29 | /**
30 | * Helper method displaying an error message to the user.
31 | **/
32 | function showErrorNotification(
33 | error: string,
34 | title: string = i18n.global.tc('generic.error')
35 | ): NotificationHandle {
36 | return showNotification(title, error, 'error');
37 | }
38 |
39 | export {showNotification, showErrorNotification};
40 |
--------------------------------------------------------------------------------
/src-vue/src/views/ChangelogView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 | {{ release.name }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
60 |
61 |
83 |
--------------------------------------------------------------------------------
/src-vue/src/views/ModsView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
show_local_mods = v"
7 | />
8 |
9 |
10 |
11 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
47 |
48 |
55 |
--------------------------------------------------------------------------------
/src-vue/src/views/PlayView.vue:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 |
36 |
Northstar
37 |
38 | {{ northstarVersion === '' ? $t('play.unknown_version') : `v${northstarVersion}` }}
39 |
40 | ({{ $t('play.see_patch_notes') }})
41 |
42 |
43 | {{ playerCount }} {{ $t('play.players') }},
44 | {{ serverCount }} {{ $t('play.servers') }}
45 |
46 |
47 | {{ $t('play.unable_to_load_playercount') }}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
{{ $t('play.northstar_running') }}
57 |
{{ northstarIsRunning }}
58 |
59 |
60 |
{{ $t('play.ea_app_running') }}
61 |
{{ $store.state.origin_is_running }}
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
125 |
--------------------------------------------------------------------------------
/src-vue/src/views/RepairView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ $t('settings.repair.window.warning') }}
6 |
7 |
8 | {{ $t('settings.repair.title') }}
9 |
10 | Northstar
11 |
12 |
13 | {{ $t('settings.repair.window.disable_all_but_core') }}
14 |
15 |
16 |
17 | {{ $t('settings.repair.window.force_reinstall_ns') }}
18 |
19 |
20 |
21 | {{ $t('settings.repair.window.kill_northstar_process') }}
22 |
23 |
24 |
25 | {{ $t('settings.repair.window.disable_modsettings') }}
26 |
27 |
28 | FlightCore
29 |
30 |
31 | {{ $t('settings.repair.window.force_delete_temp_dl') }}
32 |
33 |
34 |
35 | {{ $t('settings.repair.window.delete_persistent_store') }}
36 |
37 |
38 |
39 |
40 |
41 |
140 |
141 |
146 |
--------------------------------------------------------------------------------
/src-vue/src/views/mods/LocalModsView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('mods.local.no_mods') }}
5 |
6 |
7 |
8 |
9 | {{ $t('settings.repair.window.disable_all_but_core') }}
10 |
11 |
12 |
13 |
14 |
15 |
65 |
66 |
73 |
--------------------------------------------------------------------------------
/src-vue/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module "*.vue" {
4 | import type { DefineComponent } from "vue";
5 | const component: DefineComponent<{}, {}, any>;
6 | export default component;
7 | }
8 |
--------------------------------------------------------------------------------
/src-vue/src/vuex-shim.d.ts:
--------------------------------------------------------------------------------
1 | import { ComponentCustomProperties } from 'vue'
2 | import { Store } from 'vuex'
3 |
4 | declare module '@vue/runtime-core' {
5 | interface ComponentCustomProperties {
6 | $i18n: I18n;
7 | $route: Route;
8 | $store: Store;
9 | $t: (key: string, ...params: any[]) => string;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src-vue/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "moduleResolution": "Node",
7 | "strict": true,
8 | "jsx": "preserve",
9 | "sourceMap": true,
10 | "allowImportingTsExtensions": true,
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "esModuleInterop": true,
14 | "noEmit": true,
15 | "noUnusedLocals": true,
16 | "noUnusedParameters": true,
17 | "noFallthroughCasesInSwitch": true,
18 | "lib": ["ESNext", "DOM", "ES2018"],
19 | "skipLibCheck": true
20 | },
21 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
22 | "references": [{ "path": "./tsconfig.node.json" }]
23 | }
24 |
--------------------------------------------------------------------------------
/src-vue/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "bundler",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/src-vue/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import vue from "@vitejs/plugin-vue";
3 |
4 | // @ts-expect-error process is a nodejs global
5 | const host = process.env.TAURI_DEV_HOST;
6 |
7 | // https://vitejs.dev/config/
8 | export default defineConfig(async () => ({
9 | // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
10 | //
11 | // 1. prevent vite from obscuring rust errors
12 | clearScreen: false,
13 | // 2. tauri expects a fixed port, fail if that port is not available
14 | server: {
15 | port: 1420,
16 | strictPort: true,
17 | host: host || false,
18 | hmr: host
19 | ? {
20 | protocol: "ws",
21 | host,
22 | port: 1421,
23 | }
24 | : undefined,
25 | watch: {
26 | // 3. tell vite to ignore watching `src-tauri`
27 | ignored: ["**/src-tauri/**"],
28 | },
29 | },
30 |
31 | build: {
32 | // Tauri supports es2022
33 | target: ['es2022'],
34 | },
35 | plugins: [vue()]
36 | }));
37 |
--------------------------------------------------------------------------------