aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/dependabot.yml8
-rw-r--r--package-lock.json96
-rw-r--r--package.json4
-rw-r--r--src-tauri/Cargo.lock204
-rw-r--r--src-tauri/Cargo.toml20
-rw-r--r--src-tauri/src/constants.rs4
-rw-r--r--src-tauri/src/github/mod.rs2
-rw-r--r--src-tauri/src/github/pull_requests.rs2
-rw-r--r--src-tauri/src/main.rs384
-rw-r--r--src-tauri/src/mod_management/mod.rs24
-rw-r--r--src-tauri/src/northstar/install.rs43
-rw-r--r--src-tauri/src/northstar/mod.rs106
-rw-r--r--src-tauri/src/northstar/profile.rs17
-rw-r--r--src-tauri/src/platform_specific/linux.rs21
-rw-r--r--src-tauri/src/platform_specific/mod.rs52
-rw-r--r--src-tauri/src/platform_specific/windows.rs2
-rw-r--r--src-tauri/src/repair_and_verify/mod.rs37
-rw-r--r--src-tauri/src/util.rs52
-rw-r--r--src-tauri/tauri.conf.json2
-rw-r--r--src-vue/package-lock.json66
-rw-r--r--src-vue/package.json4
-rw-r--r--src-vue/src/App.vue4
-rw-r--r--src-vue/src/components/ThunderstoreModCard.vue2
-rw-r--r--src-vue/src/i18n/lang/en.json6
-rw-r--r--src-vue/src/plugins/store.ts21
-rw-r--r--src-vue/src/style.css8
-rw-r--r--src-vue/src/views/DeveloperView.vue4
-rw-r--r--src-vue/src/views/RepairView.vue4
-rw-r--r--src-vue/src/views/SettingsView.vue56
29 files changed, 690 insertions, 565 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 19bb8c4c..3af6e5da 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -2,6 +2,14 @@
version: 2
updates:
+ # Root NPM package
+ - package-ecosystem: 'npm'
+ directory: '/'
+ schedule:
+ interval: "daily"
+ commit-message:
+ prefix: "chore: "
+
# NPM packages
- package-ecosystem: 'npm'
directory: '/src-vue'
diff --git a/package-lock.json b/package-lock.json
index d0c6aa49..4f9238c9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,16 +6,16 @@
"": {
"name": "flightcore",
"dependencies": {
- "@tauri-apps/api": "^1.4.0"
+ "@tauri-apps/api": "^1.5.0"
},
"devDependencies": {
- "@tauri-apps/cli": "^1.4.0"
+ "@tauri-apps/cli": "^1.5.2"
}
},
"node_modules/@tauri-apps/api": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.4.0.tgz",
- "integrity": "sha512-Jd6HPoTM1PZSFIzq7FB8VmMu3qSSyo/3lSwLpoapW+lQ41CL5Dow2KryLg+gyazA/58DRWI9vu/XpEeHK4uMdw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.0.tgz",
+ "integrity": "sha512-yQY9wpVNuiYhLLuyDlu1nBpqJELT1fGp7OctN4rW9I2W1T2p7A3tqPxsEzQprEwneQRBAlPM9vC8NsnMbct+pg==",
"engines": {
"node": ">= 14.6.0",
"npm": ">= 6.6.0",
@@ -27,9 +27,9 @@
}
},
"node_modules/@tauri-apps/cli": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.4.0.tgz",
- "integrity": "sha512-VXYr2i2iVFl98etQSQsqLzXgX96bnWiNZd1YADgatqwy/qecbd6Kl5ZAPB5R4ynsgE8A1gU7Fbzh7dCEQYFfmA==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.2.tgz",
+ "integrity": "sha512-x4rPinrdyWLdTU5TbV7wrXudOyMilv0nmi1rngm/jwN3MmZdAj5J2xaS2rYtA8BU3oM/SE34qQwYxv1a2sM9ug==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -42,22 +42,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
- "@tauri-apps/cli-darwin-arm64": "1.4.0",
- "@tauri-apps/cli-darwin-x64": "1.4.0",
- "@tauri-apps/cli-linux-arm-gnueabihf": "1.4.0",
- "@tauri-apps/cli-linux-arm64-gnu": "1.4.0",
- "@tauri-apps/cli-linux-arm64-musl": "1.4.0",
- "@tauri-apps/cli-linux-x64-gnu": "1.4.0",
- "@tauri-apps/cli-linux-x64-musl": "1.4.0",
- "@tauri-apps/cli-win32-arm64-msvc": "1.4.0",
- "@tauri-apps/cli-win32-ia32-msvc": "1.4.0",
- "@tauri-apps/cli-win32-x64-msvc": "1.4.0"
+ "@tauri-apps/cli-darwin-arm64": "1.5.2",
+ "@tauri-apps/cli-darwin-x64": "1.5.2",
+ "@tauri-apps/cli-linux-arm-gnueabihf": "1.5.2",
+ "@tauri-apps/cli-linux-arm64-gnu": "1.5.2",
+ "@tauri-apps/cli-linux-arm64-musl": "1.5.2",
+ "@tauri-apps/cli-linux-x64-gnu": "1.5.2",
+ "@tauri-apps/cli-linux-x64-musl": "1.5.2",
+ "@tauri-apps/cli-win32-arm64-msvc": "1.5.2",
+ "@tauri-apps/cli-win32-ia32-msvc": "1.5.2",
+ "@tauri-apps/cli-win32-x64-msvc": "1.5.2"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.4.0.tgz",
- "integrity": "sha512-nA/ml0SfUt6/CYLVbHmT500Y+ijqsuv5+s9EBnVXYSLVg9kbPUZJJHluEYK+xKuOj6xzyuT/+rZFMRapmJD3jQ==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.2.tgz",
+ "integrity": "sha512-3mYN15jpYjuuHRWii5Xk6JvB3ZLEgAZkeVgc5Hg7k3Yw1ZBrEGiUNe3Ku4DjbkYWL/QDd7oteIJnQk3j0mXwEg==",
"cpu": [
"arm64"
],
@@ -71,9 +71,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.4.0.tgz",
- "integrity": "sha512-ov/F6Zr+dg9B0PtRu65stFo2G0ow2TUlneqYYrkj+vA3n+moWDHfVty0raDjMLQbQt3rv3uayFMXGPMgble9OA==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.2.tgz",
+ "integrity": "sha512-8Jsl+EKBGdBoRUIR5ohjiTV6uG+pFpkNwHB4WaOzzR//v6p0lGULk2ohPIjJxhoQIFIN9oBd8bsSSNbZO/57/g==",
"cpu": [
"x64"
],
@@ -87,9 +87,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.4.0.tgz",
- "integrity": "sha512-zwjbiMncycXDV7doovymyKD7sCg53ouAmfgpUqEBOTY3vgBi9TwijyPhJOqoG5vUVWhouNBC08akGmE4dja15g==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.2.tgz",
+ "integrity": "sha512-oWzcQtZogchdCSdQ+eEbDJHjJO9BGPO9EZNfvI2u3JzS/hJj4wCwnGHvZGI4jJ/6cnmcNvtt9ZftYYN4rpQW7A==",
"cpu": [
"arm"
],
@@ -103,9 +103,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.4.0.tgz",
- "integrity": "sha512-5MCBcziqXC72mMXnkZU68mutXIR6zavDxopArE2gQtK841IlE06bIgtLi0kUUhlFJk2nhPRgiDgdLbrPlyt7fw==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.2.tgz",
+ "integrity": "sha512-hfIUtys+SrrGEpLhQJwmL16g1FDhfObR4AGahCMqvMwA25uQKhtzRhxieO4X3k03vBeboTyJla5a2rX4TQ4lXA==",
"cpu": [
"arm64"
],
@@ -119,9 +119,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.4.0.tgz",
- "integrity": "sha512-7J3pRB6n6uNYgIfCeKt2Oz8J7oSaz2s8GGFRRH2HPxuTHrBNCinzVYm68UhVpJrL3bnGkU0ziVZLsW/iaOGfUg==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.2.tgz",
+ "integrity": "sha512-ZpFX4HyjkJHfF0geVVpq5fNjEXG8766LRg/BL4/wKy8MNbqcc/aW3sLEpVj0GvdulxOnd2trDb1FJdZ206Kp8g==",
"cpu": [
"arm64"
],
@@ -135,9 +135,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.4.0.tgz",
- "integrity": "sha512-Zh5gfAJxOv5AVWxcwuueaQ2vIAhlg0d6nZui6nMyfIJ8dbf3aZQ5ZzP38sYow5h/fbvgL+3GSQxZRBIa3c2E1w==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.2.tgz",
+ "integrity": "sha512-/kEZrDVZv1+qYpZigtLntX4s+gx7WQqp8cmxKZL5GrzAjUNSTnfWK5VL7o0lYm09QBJAdTvjcJu2aPzNHLDS+Q==",
"cpu": [
"x64"
],
@@ -151,9 +151,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.4.0.tgz",
- "integrity": "sha512-OLAYoICU3FaYiTdBsI+lQTKnDHeMmFMXIApN0M+xGiOkoIOQcV9CConMPjgmJQ867+NHRNgUGlvBEAh9CiJodQ==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.2.tgz",
+ "integrity": "sha512-vOrTqfW7NZLYmB1ZXjEq9JC8Z5knIHVGltN3jfyq9UY+tu7d6jNaSHuDdsVHLaKIRQajTHz+5cphDMoL+6/MUQ==",
"cpu": [
"x64"
],
@@ -167,9 +167,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.4.0.tgz",
- "integrity": "sha512-gZ05GENFbI6CB5MlOUsLlU0kZ9UtHn9riYtSXKT6MYs8HSPRffPHaHSL0WxsJweWh9nR5Hgh/TUU8uW3sYCzCg==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.2.tgz",
+ "integrity": "sha512-PCAIxH8TvIy1PlJK2qrdwpRCa7pZV648whRhmoLwj9lvn9PR4+vwuUWhSTXmp1ISHWZm/mEJpYuVq0ZxJDQKZQ==",
"cpu": [
"arm64"
],
@@ -183,9 +183,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.4.0.tgz",
- "integrity": "sha512-JsetT/lTx/Zq98eo8T5CiRyF1nKeX04RO8JlJrI3ZOYsZpp/A5RJvMd/szQ17iOzwiHdge+tx7k2jHysR6oBlQ==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.2.tgz",
+ "integrity": "sha512-0rCXZC/9qyWZI2cgVnsT4JEjcxjQcZlrZjaSwhGynPUMkIUUBsWDimzkQeOP8abw5j/kLS2QPQRHAHqd0IF6Rg==",
"cpu": [
"ia32"
],
@@ -199,9 +199,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.4.0.tgz",
- "integrity": "sha512-z8Olcnwp5aYhzqUAarFjqF+oELCjuYWnB2HAJHlfsYNfDCAORY5kct3Fklz8PSsubC3U2EugWn8n42DwnThurg==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.2.tgz",
+ "integrity": "sha512-HrOwIujKTql8yUOvR+IEGW/SXwMwPrGWrcM35cDfCxpkLH6h3F5i4JtRqYTAiFdSfTk1J2rcFVQXfFJYIDntnA==",
"cpu": [
"x64"
],
diff --git a/package.json b/package.json
index 27094072..7075ea4f 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,9 @@
"tauri": "tauri"
},
"dependencies": {
- "@tauri-apps/api": "^1.4.0"
+ "@tauri-apps/api": "^1.5.0"
},
"devDependencies": {
- "@tauri-apps/cli": "^1.4.0"
+ "@tauri-apps/cli": "^1.5.2"
}
}
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 835cdef2..b619abf4 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -80,41 +80,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
-name = "app"
-version = "2.10.3"
-dependencies = [
- "anyhow",
- "async-recursion",
- "chrono",
- "const_format",
- "dirs",
- "glob",
- "json5",
- "libthermite",
- "log",
- "open 5.0.0",
- "pretty_env_logger",
- "regex",
- "reqwest",
- "semver",
- "sentry",
- "sentry-log",
- "serde",
- "serde_json",
- "steamlocate",
- "sysinfo",
- "tauri",
- "tauri-build",
- "tauri-plugin-store",
- "tokio",
- "ts-rs",
- "winapi",
- "winreg 0.51.0",
- "zip",
- "zip-extract",
-]
-
-[[package]]
name = "async-broadcast"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1101,6 +1066,41 @@ dependencies = [
]
[[package]]
+name = "flightcore"
+version = "2.13.0"
+dependencies = [
+ "anyhow",
+ "async-recursion",
+ "chrono",
+ "const_format",
+ "dirs",
+ "glob",
+ "json5",
+ "libthermite",
+ "log",
+ "open 5.0.0",
+ "pretty_env_logger",
+ "regex",
+ "reqwest",
+ "semver",
+ "sentry",
+ "sentry-log",
+ "serde",
+ "serde_json",
+ "steamlocate",
+ "sysinfo",
+ "tauri",
+ "tauri-build",
+ "tauri-plugin-store",
+ "tokio",
+ "ts-rs",
+ "winapi",
+ "winreg 0.51.0",
+ "zip",
+ "zip-extract",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1619,7 +1619,21 @@ checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148"
dependencies = [
"log",
"mac",
- "markup5ever",
+ "markup5ever 0.10.1",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "html5ever"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever 0.11.0",
"proc-macro2",
"quote",
"syn 1.0.109",
@@ -2010,7 +2024,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358"
dependencies = [
"cssparser",
- "html5ever",
+ "html5ever 0.25.2",
+ "matches",
+ "selectors",
+]
+
+[[package]]
+name = "kuchikiki"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8"
+dependencies = [
+ "cssparser",
+ "html5ever 0.26.0",
+ "indexmap 1.9.3",
"matches",
"selectors",
]
@@ -2134,7 +2161,21 @@ checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd"
dependencies = [
"log",
"phf 0.8.0",
- "phf_codegen",
+ "phf_codegen 0.8.0",
+ "string_cache",
+ "string_cache_codegen",
+ "tendril",
+]
+
+[[package]]
+name = "markup5ever"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
+dependencies = [
+ "log",
+ "phf 0.10.1",
+ "phf_codegen 0.10.0",
"string_cache",
"string_cache_codegen",
"tendril",
@@ -2722,6 +2763,16 @@ dependencies = [
]
[[package]]
+name = "phf_codegen"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
+]
+
+[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3086,14 +3137,14 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.9.6"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
+checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.3.9",
- "regex-syntax 0.7.5",
+ "regex-automata 0.4.1",
+ "regex-syntax 0.8.0",
]
[[package]]
@@ -3107,13 +3158,13 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.3.9"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
+checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b"
dependencies = [
"aho-corasick",
"memchr",
- "regex-syntax 0.7.5",
+ "regex-syntax 0.8.0",
]
[[package]]
@@ -3124,9 +3175,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
-version = "0.7.5"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
+checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d"
[[package]]
name = "reqwest"
@@ -3375,7 +3426,7 @@ dependencies = [
"log",
"matches",
"phf 0.8.0",
- "phf_codegen",
+ "phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc",
"smallvec",
@@ -3384,9 +3435,9 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.19"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
+checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
dependencies = [
"serde",
]
@@ -3511,18 +3562,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.188"
+version = "1.0.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
+checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.188"
+version = "1.0.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
+checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
dependencies = [
"proc-macro2",
"quote",
@@ -4029,9 +4080,9 @@ checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
[[package]]
name = "tauri"
-version = "1.4.1"
+version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbe522898e35407a8e60dc3870f7579fea2fc262a6a6072eccdd37ae1e1d91e"
+checksum = "9bfe673cf125ef364d6f56b15e8ce7537d9ca7e4dae1cf6fbbdeed2e024db3d9"
dependencies = [
"anyhow",
"base64 0.21.2",
@@ -4088,12 +4139,13 @@ dependencies = [
[[package]]
name = "tauri-build"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d2edd6a259b5591c8efdeb9d5702cb53515b82a6affebd55c7fd6d3a27b7d1b"
+checksum = "defbfc551bd38ab997e5f8e458f87396d2559d05ce32095076ad6c30f7fc5f9c"
dependencies = [
"anyhow",
"cargo_toml",
+ "dirs-next",
"heck 0.4.1",
"json-patch",
"semver",
@@ -4101,13 +4153,14 @@ dependencies = [
"serde_json",
"tauri-utils",
"tauri-winres",
+ "walkdir",
]
[[package]]
name = "tauri-codegen"
-version = "1.4.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54ad2d49fdeab4a08717f5b49a163bdc72efc3b1950b6758245fcde79b645e1a"
+checksum = "7b3475e55acec0b4a50fb96435f19631fb58cbcd31923e1a213de5c382536bbb"
dependencies = [
"base64 0.21.2",
"brotli",
@@ -4131,9 +4184,9 @@ dependencies = [
[[package]]
name = "tauri-macros"
-version = "1.4.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eb12a2454e747896929338d93b0642144bb51e0dddbb36e579035731f0d76b7"
+checksum = "613740228de92d9196b795ac455091d3a5fbdac2654abb8bb07d010b62ab43af"
dependencies = [
"heck 0.4.1",
"proc-macro2",
@@ -4157,9 +4210,9 @@ dependencies = [
[[package]]
name = "tauri-runtime"
-version = "0.14.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769"
+checksum = "07f8e9e53e00e9f41212c115749e87d5cd2a9eebccafca77a19722eeecd56d43"
dependencies = [
"gtk",
"http",
@@ -4178,9 +4231,9 @@ dependencies = [
[[package]]
name = "tauri-runtime-wry"
-version = "0.14.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7aa256a1407a3a091b5d843eccc1a5042289baf0a43d1179d9f0fcfea37c1b"
+checksum = "8141d72b6b65f2008911e9ef5b98a68d1e3413b7a1464e8f85eb3673bb19a895"
dependencies = [
"cocoa",
"gtk",
@@ -4198,19 +4251,20 @@ dependencies = [
[[package]]
name = "tauri-utils"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03fc02bb6072bb397e1d473c6f76c953cda48b4a2d0cce605df284aa74a12e84"
+checksum = "34d55e185904a84a419308d523c2c6891d5e2dbcee740c4997eb42e75a7b0f46"
dependencies = [
"brotli",
"ctor",
"dunce",
"glob",
"heck 0.4.1",
- "html5ever",
+ "html5ever 0.26.0",
"infer",
"json-patch",
- "kuchiki",
+ "kuchikiki",
+ "log",
"memchr",
"phf 0.10.1",
"proc-macro2",
@@ -4359,9 +4413,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.32.0"
+version = "1.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
+checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
dependencies = [
"backtrace",
"bytes",
@@ -5292,9 +5346,9 @@ dependencies = [
[[package]]
name = "wry"
-version = "0.24.3"
+version = "0.24.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33748f35413c8a98d45f7a08832d848c0c5915501803d1faade5a4ebcd258cea"
+checksum = "88ef04bdad49eba2e01f06e53688c8413bd6a87b0bc14b72284465cf96e3578e"
dependencies = [
"base64 0.13.1",
"block",
@@ -5306,7 +5360,7 @@ dependencies = [
"gio",
"glib",
"gtk",
- "html5ever",
+ "html5ever 0.25.2",
"http",
"kuchiki",
"libc",
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index f1d26cf8..5028a9e0 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -1,11 +1,11 @@
[package]
-name = "app"
-version = "2.10.3"
-description = "A Tauri App"
-authors = ["you"]
-license = ""
-repository = ""
-default-run = "app"
+name = "flightcore"
+version = "2.13.0"
+description = "Mod-manager for Northstar"
+authors = ["https://github.com/R2NorthstarTools/FlightCore/graphs/contributors"]
+license = "MIT"
+repository = "https://github.com/R2NorthstarTools/FlightCore"
+default-run = "flightcore"
edition = "2021"
rust-version = "1.66"
@@ -18,12 +18,12 @@ rust-version = "1.66"
debug = 1
[build-dependencies]
-tauri-build = { version = "1.4", features = [] }
+tauri-build = { version = "1.5", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
-tauri = { version = "1.4", features = ["api-all", "dialog", "updater"] }
+tauri = { version = "1.5", features = ["api-all", "dialog", "updater"] }
tokio = { version = "1", features = ["full"] }
# Sentry (crash) logging
sentry = "0.31"
@@ -37,7 +37,7 @@ libthermite = { version = "0.7.0-beta", features = ["proton"] }
# zip stuff
zip = "0.6.2"
# Regex
-regex = "1.9"
+regex = "1.10"
# Read out running application process names
sysinfo = "0.29.10"
# HTTP requests
diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs
index 33aefac8..7ee98f95 100644
--- a/src-tauri/src/constants.rs
+++ b/src-tauri/src/constants.rs
@@ -58,7 +58,3 @@ pub const NORTHSTAR_DLL: &str = "Northstar.dll";
/// Profile that Northstar defaults to and ships with
pub const NORTHSTAR_DEFAULT_PROFILE: &str = "R2Northstar";
-
-/// List of valid compatibility tools that Northstar can be launched with
-pub const VALID_NORTHSTAR_PROTON_BUILDS: [&str; 3] =
- ["NorthstarProton-8.1-1", "GE-Proton8-13", "GE-Proton8-11"];
diff --git a/src-tauri/src/github/mod.rs b/src-tauri/src/github/mod.rs
index f35b64a1..0174084f 100644
--- a/src-tauri/src/github/mod.rs
+++ b/src-tauri/src/github/mod.rs
@@ -160,7 +160,7 @@ fn generate_flightcore_release_notes(commits: Vec<String>) -> String {
"feat" => "**Features:**",
"fix" => "**Bug Fixes:**",
"docs" => "**Documentation:**",
- "style" => "**Styles:**",
+ "style" => "**Code style changes:**",
"refactor" => "**Code Refactoring:**",
"build" => "**Build:**",
"test" => "**Tests:**",
diff --git a/src-tauri/src/github/pull_requests.rs b/src-tauri/src/github/pull_requests.rs
index ccb45dff..91d8a5da 100644
--- a/src-tauri/src/github/pull_requests.rs
+++ b/src-tauri/src/github/pull_requests.rs
@@ -1,7 +1,7 @@
use crate::github::release_notes::fetch_github_releases_api;
-use crate::check_is_valid_game_path;
use crate::constants::{APP_USER_AGENT, PULLS_API_ENDPOINT_LAUNCHER, PULLS_API_ENDPOINT_MODS};
+use crate::repair_and_verify::check_is_valid_game_path;
use crate::GameInstall;
use anyhow::anyhow;
use serde::{Deserialize, Serialize};
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 66bb98d2..09242680 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -9,23 +9,22 @@ use std::{
time::Duration,
};
-use crate::constants::REFRESH_DELAY;
-
+mod constants;
mod development;
mod github;
mod mod_management;
mod northstar;
+mod platform_specific;
mod repair_and_verify;
mod thunderstore;
mod util;
-use semver::Version;
use serde::{Deserialize, Serialize};
#[cfg(target_os = "windows")]
use tauri::api::dialog::blocking::MessageDialogBuilder;
#[cfg(target_os = "windows")]
use tauri::api::dialog::{MessageDialogButtons, MessageDialogKind};
-use tauri::{Manager, Runtime};
+use tauri::Manager;
use tokio::time::sleep;
use ts_rs::TS;
@@ -38,7 +37,7 @@ struct NorthstarThunderstoreRelease {
#[derive(Serialize, Deserialize, Debug, Clone, TS)]
#[ts(export)]
-struct NorthstarThunderstoreReleaseWrapper {
+pub struct NorthstarThunderstoreReleaseWrapper {
label: String,
value: NorthstarThunderstoreRelease,
}
@@ -103,7 +102,7 @@ fn main() {
let app_handle = app.app_handle();
tauri::async_runtime::spawn(async move {
loop {
- sleep(REFRESH_DELAY).await;
+ sleep(constants::REFRESH_DELAY).await;
app_handle
.emit_all(
"northstar-statistics",
@@ -119,13 +118,13 @@ fn main() {
.invoke_handler(tauri::generate_handler![
util::force_panic,
northstar::install::find_game_install_location,
- get_flightcore_version_number,
+ util::get_flightcore_version_number,
northstar::get_northstar_version_number,
- check_is_northstar_outdated,
- verify_install_location,
- get_host_os,
- install_northstar_caller,
- update_northstar,
+ northstar::check_is_northstar_outdated,
+ repair_and_verify::verify_install_location,
+ platform_specific::get_host_os,
+ northstar::install::install_northstar_wrapper,
+ northstar::install::update_northstar,
northstar::launch_northstar,
northstar::launch_northstar_steam,
github::release_notes::check_is_flightcore_outdated,
@@ -135,19 +134,19 @@ fn main() {
repair_and_verify::disable_all_but_core,
util::is_debug_mode,
github::release_notes::get_northstar_release_notes,
- linux_checks,
+ platform_specific::linux_checks,
mod_management::get_installed_mods_and_properties,
- install_mod_caller,
- clean_up_download_folder_caller,
+ mod_management::install_mod_wrapper,
+ repair_and_verify::clean_up_download_folder_wrapper,
github::release_notes::get_newest_flightcore_version,
mod_management::delete_northstar_mod,
util::get_server_player_count,
util::kill_northstar,
mod_management::delete_thunderstore_mod,
- install_northstar_proton_wrapper,
- uninstall_northstar_proton_wrapper,
- get_local_northstar_proton_wrapper_version,
- open_repair_window,
+ platform_specific::install_northstar_proton_wrapper,
+ platform_specific::uninstall_northstar_proton_wrapper,
+ platform_specific::get_local_northstar_proton_wrapper_version,
+ util::open_repair_window,
thunderstore::query_thunderstore_packages_api,
github::get_list_of_tags,
github::compare_tags,
@@ -155,11 +154,12 @@ fn main() {
github::pull_requests::apply_launcher_pr,
github::pull_requests::apply_mods_pr,
github::pull_requests::get_launcher_download_link,
- close_application,
+ util::close_application,
development::install_git_main,
- get_available_northstar_versions,
+ northstar::get_available_northstar_versions,
northstar::profile::fetch_profiles,
northstar::profile::validate_profile,
+ northstar::profile::delete_profile,
])
.run(tauri::generate_context!())
{
@@ -193,272 +193,7 @@ fn main() {
};
}
-/// Returns true if linux compatible
-#[tauri::command]
-async fn linux_checks() -> Result<(), String> {
- // Different behaviour depending on OS
- // MacOS is missing as it is not a target
- // in turn this means this application will not build on MacOS.
- #[cfg(target_os = "windows")]
- {
- Err("Not available on Windows".to_string())
- }
-
- #[cfg(target_os = "linux")]
- {
- linux_checks_librs()
- }
-}
-
-/// Returns the current version number as a string
-#[tauri::command]
-async fn get_flightcore_version_number() -> String {
- let version = env!("CARGO_PKG_VERSION");
- if cfg!(debug_assertions) {
- // Debugging enabled
- format!("v{} (debug mode)", version)
- } else {
- // Debugging disabled
- format!("v{}", version)
- }
-}
-
-/// Helps with converting release candidate numbers which are different on Thunderstore
-/// due to restrictions imposed by the platform
-pub fn convert_release_candidate_number(version_number: String) -> String {
- // This simply converts `-rc` to `0`
- // Works as intended for RCs < 10, e.g. `v1.9.2-rc1` -> `v1.9.201`
- // Doesn't work for larger numbers, e.g. `v1.9.2-rc11` -> `v1.9.2011` (should be `v1.9.211`)
- version_number.replace("-rc", "0").replace("00", "")
-}
-
-/// Checks if installed Northstar version is up-to-date
-/// false -> Northstar install is up-to-date
-/// true -> Northstar install is outdated
-#[tauri::command]
-async fn check_is_northstar_outdated(
- game_install: GameInstall,
- northstar_package_name: Option<String>,
-) -> Result<bool, String> {
- let northstar_package_name = match northstar_package_name {
- Some(northstar_package_name) => {
- if northstar_package_name.len() <= 1 {
- "Northstar".to_string()
- } else {
- northstar_package_name
- }
- }
- None => "Northstar".to_string(),
- };
-
- let index = match thermite::api::get_package_index() {
- Ok(res) => res.to_vec(),
- Err(err) => return Err(format!("Couldn't check if Northstar up-to-date: {err}")),
- };
- let nmod = index
- .iter()
- .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase())
- .expect("Couldn't find Northstar on thunderstore???");
- // .ok_or_else(|| anyhow!("Couldn't find Northstar on thunderstore???"))?;
-
- let version_number = match northstar::get_northstar_version_number(game_install) {
- Ok(version_number) => version_number,
- Err(err) => {
- log::warn!("{}", err);
- // If we fail to get new version just assume we are up-to-date
- return Err(err);
- }
- };
-
- // Release candidate version numbers are different between `mods.json` and Thunderstore
- let version_number = convert_release_candidate_number(version_number);
-
- if version_number != nmod.latest {
- log::info!("Installed Northstar version outdated");
- Ok(true)
- } else {
- log::info!("Installed Northstar version up-to-date");
- Ok(false)
- }
-}
-
-/// Checks if is valid Titanfall2 install based on certain conditions
-#[tauri::command]
-async fn verify_install_location(game_path: String) -> bool {
- match check_is_valid_game_path(&game_path) {
- Ok(()) => true,
- Err(err) => {
- log::warn!("{}", err);
- false
- }
- }
-}
-
-/// Installs Northstar to the given path
-#[tauri::command]
-async fn install_northstar_caller(
- window: tauri::Window,
- game_install: GameInstall,
- northstar_package_name: Option<String>,
- version_number: Option<String>,
-) -> Result<bool, String> {
- log::info!("Running Northstar install");
-
- // Get Northstar package name (`Northstar` vs `NorthstarReleaseCandidate`)
- let northstar_package_name = northstar_package_name
- .map(|name| {
- if name.len() <= 1 {
- "Northstar".to_string()
- } else {
- name
- }
- })
- .unwrap_or("Northstar".to_string());
-
- match northstar::install::install_northstar(
- window,
- game_install,
- northstar_package_name,
- version_number,
- )
- .await
- {
- Ok(_) => Ok(true),
- Err(err) => {
- log::error!("{}", err);
- Err(err)
- }
- }
-}
-
-/// Update Northstar install in the given path
-#[tauri::command]
-async fn update_northstar(
- window: tauri::Window,
- game_install: GameInstall,
- northstar_package_name: Option<String>,
-) -> Result<bool, String> {
- log::info!("Updating Northstar");
-
- // Simply re-run install with up-to-date version for upate
- install_northstar_caller(window, game_install, northstar_package_name, None).await
-}
-
-/// Installs the specified mod
-#[tauri::command]
-async fn install_mod_caller(
- game_install: GameInstall,
- thunderstore_mod_string: String,
-) -> Result<(), String> {
- match mod_management::fc_download_mod_and_install(&game_install, &thunderstore_mod_string).await
- {
- Ok(()) => (),
- Err(err) => {
- log::warn!("{err}");
- return Err(err);
- }
- };
- match repair_and_verify::clean_up_download_folder(&game_install, false) {
- Ok(()) => Ok(()),
- Err(err) => {
- log::info!("Failed to delete download folder due to {}", err);
- // Failure to delete download folder is not an error in mod install
- // As such ignore. User can still force delete if need be
- Ok(())
- }
- }
-}
-
-/// Installs the specified mod
-#[tauri::command]
-async fn clean_up_download_folder_caller(
- game_install: GameInstall,
- force: bool,
-) -> Result<(), String> {
- match repair_and_verify::clean_up_download_folder(&game_install, force) {
- Ok(()) => Ok(()),
- Err(err) => Err(err.to_string()),
- }
-}
-
-/// Spawns repair window
-#[tauri::command]
-async fn open_repair_window(handle: tauri::AppHandle) -> Result<(), String> {
- // Spawn new window
- let repair_window = match tauri::WindowBuilder::new(
- &handle,
- "RepairWindow",
- tauri::WindowUrl::App("/#/repair".into()),
- )
- .build()
- {
- Ok(res) => res,
- Err(err) => return Err(err.to_string()),
- };
-
- // Set window title
- match repair_window.set_title("FlightCore Repair Window") {
- Ok(()) => (),
- Err(err) => return Err(err.to_string()),
- };
- Ok(())
-}
-
-/// Closes all windows and exits application
-#[tauri::command]
-async fn close_application<R: Runtime>(app: tauri::AppHandle<R>) -> Result<(), String> {
- app.exit(0); // Close application
- Ok(())
-}
-
-/// Gets list of available Northstar versions from Thunderstore
-#[tauri::command]
-async fn get_available_northstar_versions() -> Result<Vec<NorthstarThunderstoreReleaseWrapper>, ()>
-{
- let northstar_package_name = "Northstar";
- let index = thermite::api::get_package_index().unwrap().to_vec();
- let nsmod = index
- .iter()
- .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase())
- .ok_or_else(|| panic!("Couldn't find Northstar on thunderstore???"))
- .unwrap();
-
- let mut releases: Vec<NorthstarThunderstoreReleaseWrapper> = vec![];
- for (_version_string, nsmod_version_obj) in nsmod.versions.iter() {
- let current_elem = NorthstarThunderstoreRelease {
- package: nsmod_version_obj.name.clone(),
- version: nsmod_version_obj.version.clone(),
- };
- let current_elem_wrapped = NorthstarThunderstoreReleaseWrapper {
- label: format!(
- "{} v{}",
- nsmod_version_obj.name.clone(),
- nsmod_version_obj.version.clone()
- ),
- value: current_elem,
- };
-
- releases.push(current_elem_wrapped);
- }
-
- releases.sort_by(|a, b| {
- // Parse version number
- let a_ver = Version::parse(&a.value.version).unwrap();
- let b_ver = Version::parse(&b.value.version).unwrap();
- b_ver.partial_cmp(&a_ver).unwrap() // Sort newest first
- });
-
- Ok(releases)
-}
-
-use anyhow::Result;
-
-pub mod constants;
-mod platform_specific;
-
-#[cfg(target_os = "linux")]
-use platform_specific::linux;
-
+/// Defines how Titanfall2 was installed (Steam, Origin, ...)
#[derive(Serialize, Deserialize, Debug, Clone, TS)]
#[ts(export)]
pub enum InstallType {
@@ -468,6 +203,10 @@ pub enum InstallType {
UNKNOWN,
}
+/// Object holding information of the Titanfall2 install, including
+/// - Install path
+/// - Active profile
+/// - Type of installation (Steam, Origin, ...)
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GameInstall {
pub game_path: String,
@@ -475,6 +214,7 @@ pub struct GameInstall {
pub install_type: InstallType,
}
+/// Object holding various information about a Northstar mod
#[derive(Serialize, Deserialize, Debug, Clone, TS)]
#[ts(export)]
pub struct NorthstarMod {
@@ -484,73 +224,3 @@ pub struct NorthstarMod {
pub enabled: bool,
pub directory: String,
}
-
-// I intend to add more linux related stuff to check here, so making a func
-// for now tho it only checks `ldd --version`
-// - salmon
-#[cfg(target_os = "linux")]
-pub fn linux_checks_librs() -> Result<(), String> {
- // Perform various checks in terms of Linux compatibility
- // Return early with error message if a check fails
-
- // check `ldd --version` to see if glibc is up to date for northstar proton
- let min_required_ldd_version = 2.33;
- let lddv = linux::check_glibc_v();
- if lddv < min_required_ldd_version {
- return Err(format!(
- "GLIBC is not version {} or greater",
- min_required_ldd_version
- ));
- };
-
- // All checks passed
- Ok(())
-}
-
-/// Checks whether the provided path is a valid Titanfall2 gamepath by checking against a certain set of criteria
-pub fn check_is_valid_game_path(game_install_path: &str) -> Result<(), String> {
- let path_to_titanfall2_exe = format!("{game_install_path}/Titanfall2.exe");
- let is_correct_game_path = std::path::Path::new(&path_to_titanfall2_exe).exists();
- log::info!("Titanfall2.exe exists in path? {}", is_correct_game_path);
-
- // Exit early if wrong game path
- if !is_correct_game_path {
- return Err(format!("Incorrect game path \"{game_install_path}\"")); // Return error cause wrong game path
- }
- Ok(())
-}
-
-/// Returns identifier of host OS FlightCore is running on
-#[tauri::command]
-fn get_host_os() -> String {
- env::consts::OS.to_string()
-}
-
-/// On Linux attempts to install NorthstarProton
-/// On Windows simply returns an error message
-#[tauri::command]
-async fn install_northstar_proton_wrapper() -> Result<(), String> {
- #[cfg(target_os = "linux")]
- return linux::install_ns_proton().map_err(|err| err.to_string());
-
- #[cfg(target_os = "windows")]
- Err("Not supported on Windows".to_string())
-}
-
-#[tauri::command]
-async fn uninstall_northstar_proton_wrapper() -> Result<(), String> {
- #[cfg(target_os = "linux")]
- return linux::uninstall_ns_proton();
-
- #[cfg(target_os = "windows")]
- Err("Not supported on Windows".to_string())
-}
-
-#[tauri::command]
-async fn get_local_northstar_proton_wrapper_version() -> Result<String, String> {
- #[cfg(target_os = "linux")]
- return linux::get_local_ns_proton_version();
-
- #[cfg(target_os = "windows")]
- Err("Not supported on Windows".to_string())
-}
diff --git a/src-tauri/src/mod_management/mod.rs b/src-tauri/src/mod_management/mod.rs
index a9826522..ab639b11 100644
--- a/src-tauri/src/mod_management/mod.rs
+++ b/src-tauri/src/mod_management/mod.rs
@@ -89,6 +89,30 @@ impl std::ops::Deref for TempFile {
}
}
+/// Installs the specified mod
+#[tauri::command]
+pub async fn install_mod_wrapper(
+ game_install: GameInstall,
+ thunderstore_mod_string: String,
+) -> Result<(), String> {
+ match fc_download_mod_and_install(&game_install, &thunderstore_mod_string).await {
+ Ok(()) => (),
+ Err(err) => {
+ log::warn!("{err}");
+ return Err(err);
+ }
+ };
+ match crate::repair_and_verify::clean_up_download_folder(&game_install, false) {
+ Ok(()) => Ok(()),
+ Err(err) => {
+ log::info!("Failed to delete download folder due to {}", err);
+ // Failure to delete download folder is not an error in mod install
+ // As such ignore. User can still force delete if need be
+ Ok(())
+ }
+ }
+}
+
/// Returns a serde json object of the parsed `enabledmods.json` file
pub fn get_enabled_mods(game_install: &GameInstall) -> Result<serde_json::value::Value, String> {
let enabledmods_json_path = format!(
diff --git a/src-tauri/src/northstar/install.rs b/src-tauri/src/northstar/install.rs
index 757f6c68..693d7af2 100644
--- a/src-tauri/src/northstar/install.rs
+++ b/src-tauri/src/northstar/install.rs
@@ -29,6 +29,49 @@ struct InstallProgress {
state: InstallState,
}
+/// Installs Northstar to the given path
+#[tauri::command]
+pub async fn install_northstar_wrapper(
+ window: tauri::Window,
+ game_install: GameInstall,
+ northstar_package_name: Option<String>,
+ version_number: Option<String>,
+) -> Result<bool, String> {
+ log::info!("Running Northstar install");
+
+ // Get Northstar package name (`Northstar` vs `NorthstarReleaseCandidate`)
+ let northstar_package_name = northstar_package_name
+ .map(|name| {
+ if name.len() <= 1 {
+ "Northstar".to_string()
+ } else {
+ name
+ }
+ })
+ .unwrap_or("Northstar".to_string());
+
+ match install_northstar(window, game_install, northstar_package_name, version_number).await {
+ Ok(_) => Ok(true),
+ Err(err) => {
+ log::error!("{}", err);
+ Err(err)
+ }
+ }
+}
+
+/// Update Northstar install in the given path
+#[tauri::command]
+pub async fn update_northstar(
+ window: tauri::Window,
+ game_install: GameInstall,
+ northstar_package_name: Option<String>,
+) -> Result<bool, String> {
+ log::info!("Updating Northstar");
+
+ // Simply re-run install with up-to-date version for upate
+ install_northstar_wrapper(window, game_install, northstar_package_name, None).await
+}
+
/// Copied from `papa` source code and modified
///Install N* from the provided mod
///
diff --git a/src-tauri/src/northstar/mod.rs b/src-tauri/src/northstar/mod.rs
index 4ee9ba82..d6f6d712 100644
--- a/src-tauri/src/northstar/mod.rs
+++ b/src-tauri/src/northstar/mod.rs
@@ -5,11 +5,103 @@ pub mod profile;
use crate::util::check_ea_app_or_origin_running;
use crate::{
- constants::{CORE_MODS, TITANFALL2_STEAM_ID, VALID_NORTHSTAR_PROTON_BUILDS},
- get_host_os, GameInstall, InstallType,
+ constants::{CORE_MODS, TITANFALL2_STEAM_ID},
+ platform_specific::get_host_os,
+ GameInstall, InstallType,
};
+use crate::{NorthstarThunderstoreRelease, NorthstarThunderstoreReleaseWrapper};
use anyhow::anyhow;
+/// Gets list of available Northstar versions from Thunderstore
+#[tauri::command]
+pub async fn get_available_northstar_versions(
+) -> Result<Vec<NorthstarThunderstoreReleaseWrapper>, ()> {
+ let northstar_package_name = "Northstar";
+ let index = thermite::api::get_package_index().unwrap().to_vec();
+ let nsmod = index
+ .iter()
+ .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase())
+ .ok_or_else(|| panic!("Couldn't find Northstar on thunderstore???"))
+ .unwrap();
+
+ let mut releases: Vec<NorthstarThunderstoreReleaseWrapper> = vec![];
+ for (_version_string, nsmod_version_obj) in nsmod.versions.iter() {
+ let current_elem = NorthstarThunderstoreRelease {
+ package: nsmod_version_obj.name.clone(),
+ version: nsmod_version_obj.version.clone(),
+ };
+ let current_elem_wrapped = NorthstarThunderstoreReleaseWrapper {
+ label: format!(
+ "{} v{}",
+ nsmod_version_obj.name.clone(),
+ nsmod_version_obj.version.clone()
+ ),
+ value: current_elem,
+ };
+
+ releases.push(current_elem_wrapped);
+ }
+
+ releases.sort_by(|a, b| {
+ // Parse version number
+ let a_ver = semver::Version::parse(&a.value.version).unwrap();
+ let b_ver = semver::Version::parse(&b.value.version).unwrap();
+ b_ver.partial_cmp(&a_ver).unwrap() // Sort newest first
+ });
+
+ Ok(releases)
+}
+
+/// Checks if installed Northstar version is up-to-date
+/// false -> Northstar install is up-to-date
+/// true -> Northstar install is outdated
+#[tauri::command]
+pub async fn check_is_northstar_outdated(
+ game_install: GameInstall,
+ northstar_package_name: Option<String>,
+) -> Result<bool, String> {
+ let northstar_package_name = match northstar_package_name {
+ Some(northstar_package_name) => {
+ if northstar_package_name.len() <= 1 {
+ "Northstar".to_string()
+ } else {
+ northstar_package_name
+ }
+ }
+ None => "Northstar".to_string(),
+ };
+
+ let index = match thermite::api::get_package_index() {
+ Ok(res) => res.to_vec(),
+ Err(err) => return Err(format!("Couldn't check if Northstar up-to-date: {err}")),
+ };
+ let nmod = index
+ .iter()
+ .find(|f| f.name.to_lowercase() == northstar_package_name.to_lowercase())
+ .expect("Couldn't find Northstar on thunderstore???");
+ // .ok_or_else(|| anyhow!("Couldn't find Northstar on thunderstore???"))?;
+
+ let version_number = match get_northstar_version_number(game_install) {
+ Ok(version_number) => version_number,
+ Err(err) => {
+ log::warn!("{}", err);
+ // If we fail to get new version just assume we are up-to-date
+ return Err(err);
+ }
+ };
+
+ // Release candidate version numbers are different between `mods.json` and Thunderstore
+ let version_number = crate::util::convert_release_candidate_number(version_number);
+
+ if version_number != nmod.latest {
+ log::info!("Installed Northstar version outdated");
+ Ok(true)
+ } else {
+ log::info!("Installed Northstar version up-to-date");
+ Ok(false)
+ }
+}
+
/// Check version number of a mod
pub fn check_mod_version_number(path_to_mod_folder: &str) -> Result<String, anyhow::Error> {
let data = std::fs::read_to_string(format!("{path_to_mod_folder}/mod.json"))?;
@@ -158,15 +250,7 @@ pub fn launch_northstar_steam(
if get_host_os() != "windows" {
let titanfall2_steamid: u32 = TITANFALL2_STEAM_ID.parse().unwrap();
match steamdir.compat_tool(&titanfall2_steamid) {
- Some(compat) => {
- if !VALID_NORTHSTAR_PROTON_BUILDS
- .contains(&compat.clone().name.unwrap().as_str())
- {
- return Err(
- "Titanfall2 was not configured to use a valid version of NorthstarProton or GE-Proton".to_string(),
- );
- }
- }
+ Some(_) => {}
None => {
return Err(
"Titanfall2 was not configured to use a compatibility tool".to_string()
diff --git a/src-tauri/src/northstar/profile.rs b/src-tauri/src/northstar/profile.rs
index 78e734d0..b0c6c418 100644
--- a/src-tauri/src/northstar/profile.rs
+++ b/src-tauri/src/northstar/profile.rs
@@ -74,3 +74,20 @@ pub fn validate_profile(game_install: GameInstall, profile: String) -> bool {
profile_dir.is_dir()
}
+
+#[tauri::command]
+pub fn delete_profile(game_install: GameInstall, profile: String) -> Result<(), String> {
+ // Check if the Profile actually exists
+ if !validate_profile(game_install.clone(), profile.clone()) {
+ return Err(format!("{} is not a valid Profile", profile));
+ }
+
+ log::info!("Deleting Profile {}", profile);
+
+ let profile_path = format!("{}/{}", game_install.game_path, profile);
+
+ match std::fs::remove_dir_all(profile_path) {
+ Ok(()) => Ok(()),
+ Err(err) => Err(format!("Failed to delete Profile: {}", err)),
+ }
+}
diff --git a/src-tauri/src/platform_specific/linux.rs b/src-tauri/src/platform_specific/linux.rs
index 674f384b..706a4d22 100644
--- a/src-tauri/src/platform_specific/linux.rs
+++ b/src-tauri/src/platform_specific/linux.rs
@@ -3,6 +3,27 @@
use regex::Regex;
use std::process::Command;
+// I intend to add more linux related stuff to check here, so making a func
+// for now tho it only checks `ldd --version`
+// - salmon
+pub fn linux_checks_librs() -> Result<(), String> {
+ // Perform various checks in terms of Linux compatibility
+ // Return early with error message if a check fails
+
+ // check `ldd --version` to see if glibc is up to date for northstar proton
+ let min_required_ldd_version = 2.33;
+ let lddv = check_glibc_v();
+ if lddv < min_required_ldd_version {
+ return Err(format!(
+ "GLIBC is not version {} or greater",
+ min_required_ldd_version
+ ));
+ };
+
+ // All checks passed
+ Ok(())
+}
+
fn get_proton_dir() -> Option<String> {
let steam_dir = steamlocate::SteamDir::locate()?;
let compat_dir = format!("{}/compatibilitytools.d/", steam_dir.path.display());
diff --git a/src-tauri/src/platform_specific/mod.rs b/src-tauri/src/platform_specific/mod.rs
index 84bd478a..8dca9424 100644
--- a/src-tauri/src/platform_specific/mod.rs
+++ b/src-tauri/src/platform_specific/mod.rs
@@ -3,3 +3,55 @@ pub mod windows;
#[cfg(target_os = "linux")]
pub mod linux;
+
+/// Returns identifier of host OS FlightCore is running on
+#[tauri::command]
+pub fn get_host_os() -> String {
+ std::env::consts::OS.to_string()
+}
+
+/// On Linux attempts to install NorthstarProton
+/// On Windows simply returns an error message
+#[tauri::command]
+pub async fn install_northstar_proton_wrapper() -> Result<(), String> {
+ #[cfg(target_os = "linux")]
+ return linux::install_ns_proton().map_err(|err| err.to_string());
+
+ #[cfg(target_os = "windows")]
+ Err("Not supported on Windows".to_string())
+}
+
+#[tauri::command]
+pub async fn uninstall_northstar_proton_wrapper() -> Result<(), String> {
+ #[cfg(target_os = "linux")]
+ return linux::uninstall_ns_proton();
+
+ #[cfg(target_os = "windows")]
+ Err("Not supported on Windows".to_string())
+}
+
+#[tauri::command]
+pub async fn get_local_northstar_proton_wrapper_version() -> Result<String, String> {
+ #[cfg(target_os = "linux")]
+ return linux::get_local_ns_proton_version();
+
+ #[cfg(target_os = "windows")]
+ Err("Not supported on Windows".to_string())
+}
+
+/// Returns true if linux compatible
+#[tauri::command]
+pub async fn linux_checks() -> Result<(), String> {
+ // Different behaviour depending on OS
+ // MacOS is missing as it is not a target
+ // in turn this means this application will not build on MacOS.
+ #[cfg(target_os = "windows")]
+ {
+ Err("Not available on Windows".to_string())
+ }
+
+ #[cfg(target_os = "linux")]
+ {
+ linux::linux_checks_librs()
+ }
+}
diff --git a/src-tauri/src/platform_specific/windows.rs b/src-tauri/src/platform_specific/windows.rs
index 899ab2cd..678e5be5 100644
--- a/src-tauri/src/platform_specific/windows.rs
+++ b/src-tauri/src/platform_specific/windows.rs
@@ -4,7 +4,7 @@ use anyhow::{anyhow, Result};
#[cfg(target_os = "windows")]
use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey};
-use crate::check_is_valid_game_path;
+use crate::repair_and_verify::check_is_valid_game_path;
/// Gets Titanfall2 install location on Origin
pub fn origin_install_location_detection() -> Result<String, anyhow::Error> {
diff --git a/src-tauri/src/repair_and_verify/mod.rs b/src-tauri/src/repair_and_verify/mod.rs
index 70abc127..c752a3ab 100644
--- a/src-tauri/src/repair_and_verify/mod.rs
+++ b/src-tauri/src/repair_and_verify/mod.rs
@@ -2,6 +2,31 @@ use crate::mod_management::{get_enabled_mods, rebuild_enabled_mods_json, set_mod
/// Contains various functions to repair common issues and verifying installation
use crate::{constants::CORE_MODS, GameInstall};
+/// Checks if is valid Titanfall2 install based on certain conditions
+#[tauri::command]
+pub async fn verify_install_location(game_path: String) -> bool {
+ match check_is_valid_game_path(&game_path) {
+ Ok(()) => true,
+ Err(err) => {
+ log::warn!("{}", err);
+ false
+ }
+ }
+}
+
+/// Checks whether the provided path is a valid Titanfall2 gamepath by checking against a certain set of criteria
+pub fn check_is_valid_game_path(game_install_path: &str) -> Result<(), String> {
+ let path_to_titanfall2_exe = format!("{game_install_path}/Titanfall2.exe");
+ let is_correct_game_path = std::path::Path::new(&path_to_titanfall2_exe).exists();
+ log::info!("Titanfall2.exe exists in path? {}", is_correct_game_path);
+
+ // Exit early if wrong game path
+ if !is_correct_game_path {
+ return Err(format!("Incorrect game path \"{game_install_path}\"")); // Return error cause wrong game path
+ }
+ Ok(())
+}
+
/// Verifies Titanfall2 game files
#[tauri::command]
pub fn verify_game_files(game_install: GameInstall) -> Result<String, String> {
@@ -32,6 +57,18 @@ pub fn disable_all_but_core(game_install: GameInstall) -> Result<(), String> {
Ok(())
}
+/// Installs the specified mod
+#[tauri::command]
+pub async fn clean_up_download_folder_wrapper(
+ game_install: GameInstall,
+ force: bool,
+) -> Result<(), String> {
+ match clean_up_download_folder(&game_install, force) {
+ Ok(()) => Ok(()),
+ Err(err) => Err(err.to_string()),
+ }
+}
+
/// Deletes download folder
/// If `force` is FALSE, bails on non-empty folder
/// If `force` is TRUE, deletes folder even if non-empty
diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs
index b21b2208..75555f3e 100644
--- a/src-tauri/src/util.rs
+++ b/src-tauri/src/util.rs
@@ -26,6 +26,49 @@ pub async fn is_debug_mode() -> bool {
cfg!(debug_assertions)
}
+/// Returns the current version number as a string
+#[tauri::command]
+pub async fn get_flightcore_version_number() -> String {
+ let version = env!("CARGO_PKG_VERSION");
+ if cfg!(debug_assertions) {
+ // Debugging enabled
+ format!("v{} (debug mode)", version)
+ } else {
+ // Debugging disabled
+ format!("v{}", version)
+ }
+}
+
+/// Spawns repair window
+#[tauri::command]
+pub async fn open_repair_window(handle: tauri::AppHandle) -> Result<(), String> {
+ // Spawn new window
+ let repair_window = match tauri::WindowBuilder::new(
+ &handle,
+ "RepairWindow",
+ tauri::WindowUrl::App("/#/repair".into()),
+ )
+ .build()
+ {
+ Ok(res) => res,
+ Err(err) => return Err(err.to_string()),
+ };
+
+ // Set window title
+ match repair_window.set_title("FlightCore Repair Window") {
+ Ok(()) => (),
+ Err(err) => return Err(err.to_string()),
+ };
+ Ok(())
+}
+
+/// Closes all windows and exits application
+#[tauri::command]
+pub async fn close_application<R: tauri::Runtime>(app: tauri::AppHandle<R>) -> Result<(), String> {
+ app.exit(0); // Close application
+ Ok(())
+}
+
/// Fetches `/client/servers` endpoint from master server
async fn fetch_server_list() -> Result<String, anyhow::Error> {
let url = format!("{MASTER_SERVER_URL}{SERVER_BROWSER_ENDPOINT}");
@@ -182,3 +225,12 @@ pub fn move_dir_all(
}
Ok(())
}
+
+/// Helps with converting release candidate numbers which are different on Thunderstore
+/// due to restrictions imposed by the platform
+pub fn convert_release_candidate_number(version_number: String) -> String {
+ // This simply converts `-rc` to `0`
+ // Works as intended for RCs < 10, e.g. `v1.9.2-rc1` -> `v1.9.201`
+ // Doesn't work for larger numbers, e.g. `v1.9.2-rc11` -> `v1.9.2011` (should be `v1.9.211`)
+ version_number.replace("-rc", "0").replace("00", "")
+}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index dd638241..f9ab1583 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -8,7 +8,7 @@
},
"package": {
"productName": "FlightCore",
- "version": "2.10.3"
+ "version": "2.13.0"
},
"tauri": {
"allowlist": {
diff --git a/src-vue/package-lock.json b/src-vue/package-lock.json
index ded2414b..efe0d2b0 100644
--- a/src-vue/package-lock.json
+++ b/src-vue/package-lock.json
@@ -10,7 +10,7 @@
"dependencies": {
"@element-plus/icons-vue": "^2.0.9",
"element-plus": "^2.3.14",
- "marked": "^9.1.0",
+ "marked": "^9.1.1",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014",
"vue": "^3.2.37",
"vue-i18n": "^9.5.0",
@@ -22,7 +22,7 @@
"@vitejs/plugin-vue": "^3.1.0",
"typescript": "^5.2.2",
"vite": "^3.1.0",
- "vue-tsc": "^1.8.15"
+ "vue-tsc": "^1.8.19"
}
},
"node_modules/@babel/parser": {
@@ -218,30 +218,30 @@
}
},
"node_modules/@volar/language-core": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.1.tgz",
- "integrity": "sha512-JnsM1mIPdfGPxmoOcK1c7HYAsL6YOv0TCJ4aW3AXPZN/Jb4R77epDyMZIVudSGjWMbvv/JfUa+rQ+dGKTmgwBA==",
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.4.tgz",
+ "integrity": "sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==",
"dev": true,
"dependencies": {
- "@volar/source-map": "1.10.1"
+ "@volar/source-map": "1.10.4"
}
},
"node_modules/@volar/source-map": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.1.tgz",
- "integrity": "sha512-3/S6KQbqa7pGC8CxPrg69qHLpOvkiPHGJtWPkI/1AXCsktkJ6gIk/5z4hyuMp8Anvs6eS/Kvp/GZa3ut3votKA==",
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.4.tgz",
+ "integrity": "sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==",
"dev": true,
"dependencies": {
"muggle-string": "^0.3.1"
}
},
"node_modules/@volar/typescript": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.1.tgz",
- "integrity": "sha512-+iiO9yUSRHIYjlteT+QcdRq8b44qH19/eiUZtjNtuh6D9ailYM7DVR0zO2sEgJlvCaunw/CF9Ov2KooQBpR4VQ==",
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.4.tgz",
+ "integrity": "sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==",
"dev": true,
"dependencies": {
- "@volar/language-core": "1.10.1"
+ "@volar/language-core": "1.10.4"
}
},
"node_modules/@vue/compiler-core": {
@@ -296,17 +296,17 @@
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
},
"node_modules/@vue/language-core": {
- "version": "1.8.15",
- "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.15.tgz",
- "integrity": "sha512-zche5Aw8kkvp3YaghuLiOZyVIpoWHjSQ0EfjxGSsqHOPMamdCoa9x3HtbenpR38UMUoKJ88wiWuiOrV3B/Yq+A==",
+ "version": "1.8.19",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.19.tgz",
+ "integrity": "sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==",
"dev": true,
"dependencies": {
- "@volar/language-core": "~1.10.0",
- "@volar/source-map": "~1.10.0",
+ "@volar/language-core": "~1.10.4",
+ "@volar/source-map": "~1.10.4",
"@vue/compiler-dom": "^3.3.0",
"@vue/reactivity": "^3.3.0",
"@vue/shared": "^3.3.0",
- "minimatch": "^9.0.0",
+ "minimatch": "^9.0.3",
"muggle-string": "^0.3.1",
"vue-template-compiler": "^2.7.14"
},
@@ -376,13 +376,13 @@
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
},
"node_modules/@vue/typescript": {
- "version": "1.8.15",
- "resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.15.tgz",
- "integrity": "sha512-qWyanQKXOsK84S8rP7QBrqsvUdQ0nZABZmTjXMpb3ox4Bp5IbkscREA3OPUrkgl64mAxwwCzIWcOc3BPTCPjQw==",
+ "version": "1.8.19",
+ "resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.19.tgz",
+ "integrity": "sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==",
"dev": true,
"dependencies": {
- "@volar/typescript": "~1.10.0",
- "@vue/language-core": "1.8.15"
+ "@volar/typescript": "~1.10.4",
+ "@vue/language-core": "1.8.19"
}
},
"node_modules/@vueuse/core": {
@@ -993,9 +993,9 @@
}
},
"node_modules/marked": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.0.tgz",
- "integrity": "sha512-VZjm0PM5DMv7WodqOUps3g6Q7dmxs9YGiFUZ7a2majzQTTCgX+6S6NAJHPvOhgFBzYz8s4QZKWWMfZKFmsfOgA==",
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.1.tgz",
+ "integrity": "sha512-ZmXkUGH54U4rEy3GL9vYj8+S1PHJx/zz5pc4Frn7UdGiNREKT12fWBJ5a5ffjFtghx9C9912vEg9Zra1Nf7CnA==",
"bin": {
"marked": "bin/marked.js"
},
@@ -1289,14 +1289,14 @@
}
},
"node_modules/vue-tsc": {
- "version": "1.8.15",
- "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.15.tgz",
- "integrity": "sha512-4DoB3LUj7IToLmggoCxRiFG+QU5lem0nv03m1ocqugXA9rSVoTOEoYYaP8vu8b99Eh+/cCVdYOeIAQ+RsgUYUw==",
+ "version": "1.8.19",
+ "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.19.tgz",
+ "integrity": "sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==",
"dev": true,
"dependencies": {
- "@vue/language-core": "1.8.15",
- "@vue/typescript": "1.8.15",
- "semver": "^7.3.8"
+ "@vue/language-core": "1.8.19",
+ "@vue/typescript": "1.8.19",
+ "semver": "^7.5.4"
},
"bin": {
"vue-tsc": "bin/vue-tsc.js"
diff --git a/src-vue/package.json b/src-vue/package.json
index e4c8c49f..5d7ede3c 100644
--- a/src-vue/package.json
+++ b/src-vue/package.json
@@ -11,7 +11,7 @@
"dependencies": {
"@element-plus/icons-vue": "^2.0.9",
"element-plus": "^2.3.14",
- "marked": "^9.1.0",
+ "marked": "^9.1.1",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014",
"vue": "^3.2.37",
"vue-i18n": "^9.5.0",
@@ -23,6 +23,6 @@
"@vitejs/plugin-vue": "^3.1.0",
"typescript": "^5.2.2",
"vite": "^3.1.0",
- "vue-tsc": "^1.8.15"
+ "vue-tsc": "^1.8.19"
}
}
diff --git a/src-vue/src/App.vue b/src-vue/src/App.vue
index f80e000d..30e5e683 100644
--- a/src-vue/src/App.vue
+++ b/src-vue/src/App.vue
@@ -34,9 +34,6 @@ export default {
this.$root!.$i18n.locale = lang;
},
methods: {
- async toggleMaximize() {
- await appWindow.toggleMaximize();
- },
minimize() {
appWindow.minimize()
},
@@ -77,7 +74,6 @@ export default {
<!-- Window controls -->
<div id="fc_window__controls">
<el-button color="white" icon="SemiSelect" @click="minimize" circle />
- <el-button color="white" icon="FullScreen" @click="toggleMaximize" circle />
<el-button color="white" icon="CloseBold" @click="close" circle />
</div>
</nav>
diff --git a/src-vue/src/components/ThunderstoreModCard.vue b/src-vue/src/components/ThunderstoreModCard.vue
index 54241e85..11be7545 100644
--- a/src-vue/src/components/ThunderstoreModCard.vue
+++ b/src-vue/src/components/ThunderstoreModCard.vue
@@ -243,7 +243,7 @@ export default defineComponent({
// Capture translation method in a context, so it can be used outside Vue component context.
// (see https://github.com/R2NorthstarTools/FlightCore/issues/384)
(async (translate: Function) => {
- await invoke<string>("install_mod_caller", { gameInstall: this.$store.state.game_install, thunderstoreModString: this.latestVersion.full_name }).then((message) => {
+ await invoke<string>("install_mod_wrapper", { gameInstall: this.$store.state.game_install, thunderstoreModString: this.latestVersion.full_name }).then((message) => {
showNotification(translate('mods.card.install_success', { modName: mod.name }), message);
})
.catch((error) => {
diff --git a/src-vue/src/i18n/lang/en.json b/src-vue/src/i18n/lang/en.json
index 2b056655..2bf18c2e 100644
--- a/src-vue/src/i18n/lang/en.json
+++ b/src-vue/src/i18n/lang/en.json
@@ -11,6 +11,7 @@
"yes": "Yes",
"no": "No",
"error": "Error",
+ "confirm": "Confirm",
"cancel": "Cancel",
"informationShort": "Info",
"downloading": "Downloading",
@@ -115,7 +116,10 @@
"edit": "Edit Profiles",
"dialog": {
- "title": "Profiles"
+ "title": "Profiles",
+ "delete_confirm": "Are you sure to delete this profile?",
+ "delete": "Delete",
+ "clone": "Clone"
}
},
diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts
index b0eaaf65..2b9b03c8 100644
--- a/src-vue/src/plugins/store.ts
+++ b/src-vue/src/plugins/store.ts
@@ -62,7 +62,7 @@ export const store = createStore<FlightCoreStore>({
state(): FlightCoreStore {
return {
developer_mode: false,
- game_install: {} as unknown as GameInstall,
+ game_install: {game_path: undefined, profile: undefined, install_type: "UNKNOWN"} as unknown as GameInstall,
available_profiles: [],
@@ -152,8 +152,15 @@ export const store = createStore<FlightCoreStore>({
await persistentStore.set('game-install', { value: state.game_install });
await persistentStore.save(); // explicit save to disk
+ // We can no longer be sure if our last profile is valid, lets reset to be sure
+ state.game_install.profile = "R2Northstar";
+
// Check for Northstar install
store.commit('checkNorthstarUpdates');
+
+ // Since we are in a new game directory, lets see if there are any profiles
+ store.commit('fetchProfiles');
+
}
else {
// Not valid Titanfall2 install
@@ -184,7 +191,7 @@ export const store = createStore<FlightCoreStore>({
switch (state.northstar_state) {
// Install northstar if it wasn't detected.
case NorthstarState.INSTALL:
- let install_northstar_result = invoke("install_northstar_caller", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal });
+ let install_northstar_result = invoke("install_northstar_wrapper", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal });
state.northstar_state = NorthstarState.INSTALLING;
await install_northstar_result.then((message) => {
@@ -201,7 +208,7 @@ export const store = createStore<FlightCoreStore>({
// Update northstar if it is outdated.
case NorthstarState.MUST_UPDATE:
// Updating is the same as installing, simply overwrites the existing files
- let reinstall_northstar_result = invoke("install_northstar_caller", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal });
+ let reinstall_northstar_result = invoke("install_northstar_wrapper", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal });
state.northstar_state = NorthstarState.UPDATING;
await reinstall_northstar_result.then((message) => {
@@ -324,6 +331,12 @@ export const store = createStore<FlightCoreStore>({
);
},
async fetchProfiles(state: FlightCoreStore) {
+ // To fetch profiles we need a valid game path
+ if (!state.game_install.game_path) {
+ return;
+ }
+
+
await invoke("fetch_profiles", { gameInstall: state.game_install })
.then((message) => {
state.available_profiles = message as string[];
@@ -435,8 +448,6 @@ async function _initializeApp(state: any) {
await _get_northstar_version_number(state);
}
- store.commit('fetchProfiles');
-
await invoke<[number, number]>("get_server_player_count")
.then((message) => {
state.player_count = message[0];
diff --git a/src-vue/src/style.css b/src-vue/src/style.css
index c66a6248..dfe682bf 100644
--- a/src-vue/src/style.css
+++ b/src-vue/src/style.css
@@ -46,3 +46,11 @@ body {
color: white;
margin: 30px 15px;
}
+
+.el-popper {
+ width: 200px !important;
+}
+
+.el-popconfirm {
+ word-break: break-word;
+}
diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue
index 206d425b..1b455452 100644
--- a/src-vue/src/views/DeveloperView.vue
+++ b/src-vue/src/views/DeveloperView.vue
@@ -249,7 +249,7 @@ export default defineComponent({
},
async installMod() {
let mod_to_install = this.mod_to_install_field_string;
- await invoke<string>("install_mod_caller", { gameInstall: this.$store.state.game_install, thunderstoreModString: mod_to_install }).then((message) => {
+ await invoke<string>("install_mod_wrapper", { gameInstall: this.$store.state.game_install, thunderstoreModString: mod_to_install }).then((message) => {
// Show user notification if mod install completed.
showNotification(`Installed ${mod_to_install}`, message);
})
@@ -317,7 +317,7 @@ export default defineComponent({
0
);
- let install_northstar_result = invoke("install_northstar_caller", { gameInstall: this.$store.state.game_install, northstarPackageName: this.selected_ns_version.value.package, versionNumber: this.selected_ns_version.value.version });
+ let install_northstar_result = invoke("install_northstar_wrapper", { gameInstall: this.$store.state.game_install, northstarPackageName: this.selected_ns_version.value.package, versionNumber: this.selected_ns_version.value.version });
await install_northstar_result
.then((message) => {
diff --git a/src-vue/src/views/RepairView.vue b/src-vue/src/views/RepairView.vue
index ce7e154d..341dff2d 100644
--- a/src-vue/src/views/RepairView.vue
+++ b/src-vue/src/views/RepairView.vue
@@ -75,7 +75,7 @@ export default defineComponent({
0
);
- let install_northstar_result = invoke("install_northstar_caller", { gameInstall: this.$store.state.game_install, northstarPackageName: ReleaseCanal.RELEASE });
+ let install_northstar_result = invoke("install_northstar_wrapper", { gameInstall: this.$store.state.game_install, northstarPackageName: ReleaseCanal.RELEASE });
appWindow.listen<InstallProgress>(
'northstar-install-download-progress',
@@ -102,7 +102,7 @@ export default defineComponent({
});
},
async cleanUpDownloadFolder() {
- await invoke("clean_up_download_folder_caller", { gameInstall: this.$store.state.game_install, force: true }).then((message) => {
+ await invoke("clean_up_download_folder_wrapper", { gameInstall: this.$store.state.game_install, force: true }).then((message) => {
// Show user notification if task completed.
showNotification(this.$t('generic.done'), this.$t('generic.done'));
})
diff --git a/src-vue/src/views/SettingsView.vue b/src-vue/src/views/SettingsView.vue
index b1a62c56..70bffbc5 100644
--- a/src-vue/src/views/SettingsView.vue
+++ b/src-vue/src/views/SettingsView.vue
@@ -6,6 +6,23 @@
>
<el-table :data="availableProfiles" >
<el-table-column prop="name" label="Name" />
+ <el-table-column align="right">
+ <template #default="scope">
+ <el-popconfirm
+ v-if="scope.row.name != 'R2Northstar'"
+ :title="$t('settings.profile.dialog.delete_confirm')"
+ :confirm-button-text="$t('generic.yes')"
+ :cancel-button-text="$t('generic.no')"
+ @confirm="deleteProfile(scope.row.name)"
+ >
+ <template #reference>
+ <el-button type="danger">
+ {{ $t('settings.profile.dialog.delete') }}
+ </el-button>
+ </template>
+ </el-popconfirm>
+ </template>
+ </el-table-column>
</el-table>
</el-dialog>
@@ -34,9 +51,9 @@
<!-- Northstar Active Profile -->
<div class="fc_parameter__panel" v-if="$store.state.developer_mode">
<h3>{{ $t('settings.profile.active') }}</h3>
- <el-dropdown trigger="click">
+ <el-dropdown trigger="click" :disabled="!availableProfiles.length">
<el-button>
- {{ $store.state.game_install.profile }} <el-icon class="el-icon--right"><arrow-down /></el-icon>
+ {{ activeProfile }} <el-icon class="el-icon--right" v-if="availableProfiles.length"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
@@ -173,7 +190,10 @@ export default defineComponent({
await persistentStore.save(); // explicit save to disk
}
},
- availableProfiles(): Object {
+ activeProfile(): String {
+ return this.$store.state.game_install.profile || "None";
+ },
+ availableProfiles(): Object[] {
let profiles = this.$store.state.available_profiles
// convert string array to object array so we can fill a table
@@ -209,6 +229,15 @@ export default defineComponent({
});
},
async openGameInstallFolder() {
+ // Verify the game path is actually set
+ if (!this.$store.state.game_install.game_path) {
+ showErrorNotification(
+ i18n.global.tc('notification.game_folder.not_found.text'),
+ i18n.global.tc('notification.game_folder.not_found.title')
+ );
+ return;
+ }
+
// Opens the folder in default file explorer application
await open(`${this.$store.state.game_install.game_path}`);
},
@@ -244,10 +273,29 @@ export default defineComponent({
console.error(error);
showErrorNotification(error);
});
- }
+ },
+ async deleteProfile(profile: string) {
+ let store = this.$store;
+ await invoke("delete_profile", {
+ gameInstall: store.state.game_install,
+ profile: profile,
+ }).then(async (message) => {
+ if (profile == store.state.game_install.profile)
+ {
+ // trying to delete the active profile, lets switch to the default profile
+ await this.switchProfile("R2Northstar");
+ }
+ store.commit('fetchProfiles');
+ showNotification('Success');
+ }).catch((error) => {
+ console.error(error);
+ showErrorNotification(error);
+ });
+ },
},
mounted() {
document.querySelector('input')!.disabled = true;
+ this.$store.commit('fetchProfiles');
},
unmounted() {
if (('' + this.modsPerPage) === '') {