Compare commits
7 Commits
3.1.0
...
b6616a37f4
| Author | SHA1 | Date | |
|---|---|---|---|
| b6616a37f4 | |||
| 63433ac626 | |||
| 149b4715d7 | |||
| ae3443d0b9 | |||
| abc7b9d9d9 | |||
| d9dd21d3be | |||
| 0df31178f4 |
@@ -19,7 +19,11 @@
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"lucide-svelte": "^0.562.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-to-webcomponent": "^2.0.1",
|
||||
"semver": "^7.7.2",
|
||||
"sileo": "^0.1.3",
|
||||
"svelte-confetti": "^2.3.2",
|
||||
"tw-animate-css": "^1.3.8",
|
||||
},
|
||||
@@ -27,13 +31,14 @@
|
||||
"@eslint/compat": "^2.0.0",
|
||||
"@eslint/js": "^9.35.0",
|
||||
"@iarna/toml": "2.2.5",
|
||||
"@lucide/svelte": "^0.482.0",
|
||||
"@lucide/svelte": "^0.562.0",
|
||||
"@sveltejs/adapter-static": "^3.0.9",
|
||||
"@sveltejs/kit": "^2.37.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.1.4",
|
||||
"@tauri-apps/cli": "^2.9.6",
|
||||
"@types/bun": "^1.2.21",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/semver": "^7.7.1",
|
||||
"autoprefixer": "10.4.21",
|
||||
"bits-ui": "^1.4.7",
|
||||
@@ -174,7 +179,7 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@lucide/svelte": ["@lucide/svelte@0.482.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-n2ycHU9cNcleRDwwpEHBJ6pYzVhHIaL3a+9dQa8kns9hB2g05bY+v2p2KP8v0pZwtNhYTHk/F2o2uZ1bVtQGhw=="],
|
||||
"@lucide/svelte": ["@lucide/svelte@0.562.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-wDMULwtTFN2Sc/TFBm6gfuVCNb4Y5P9LDrwxNnUbV52+IEU7NXZmvxwXoz+vrrpad6Xupq+Hw5eUlqIHEGhouw=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
@@ -214,6 +219,8 @@
|
||||
|
||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||
|
||||
"@r2wc/core": ["@r2wc/core@1.3.0", "", {}, "sha512-aPBnND92Itl+SWWbWyyxdFFF0+RqKB6dptGHEdiPB8ZvnHWHlVzOfEvbEcyUYGtB6HBdsfkVuBiaGYyBFVTzVQ=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.1", "", { "os": "android", "cpu": "arm" }, "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.1", "", { "os": "android", "cpu": "arm64" }, "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ=="],
|
||||
@@ -346,6 +353,8 @@
|
||||
|
||||
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||
|
||||
"@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
|
||||
|
||||
"@types/umami": ["@types/umami@2.10.1", "", {}, "sha512-CvOEMq+BFOUXj8yciq4hPsdOt0o9KBg5jQXnF1FrdOMKZMxJiwryyZNLa9Ud2NVO6nXSwU22YMKR3E+Xhbo+DA=="],
|
||||
@@ -506,6 +515,8 @@
|
||||
|
||||
"fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.34.1", "", { "dependencies": { "motion-dom": "^12.34.1", "motion-utils": "^12.29.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-kcZyNaYQfvE2LlH6+AyOaJAQV4rGp5XbzfhsZpiSZcwDMfZUHhuxLWeyRzf5I7jip3qKRpuimPA9pXXfr111kQ=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
@@ -610,6 +621,12 @@
|
||||
|
||||
"mode-watcher": ["mode-watcher@1.1.0", "", { "dependencies": { "runed": "^0.25.0", "svelte-toolbelt": "^0.7.1" }, "peerDependencies": { "svelte": "^5.27.0" } }, "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g=="],
|
||||
|
||||
"motion": ["motion@12.34.1", "", { "dependencies": { "framer-motion": "^12.34.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-N9RVNGn/NSo85OgHX1wGaUWHvReuQ7dZUwuQRhHyzY2wfVOvY3cEgn0Mw4NXOsXMHL/y7EYuzA+b59PYI6EejA=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.34.1", "", { "dependencies": { "motion-utils": "^12.29.2" } }, "sha512-SC7ZC5dRcGwku2g7EsPvI4q/EzHumUbqsDNumBmZTLFg+goBO5LTJvDu9MAxx+0mtX4IA78B2be/A3aRjY0jnw=="],
|
||||
|
||||
"motion-utils": ["motion-utils@12.29.2", "", {}, "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A=="],
|
||||
|
||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||
|
||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||
@@ -666,6 +683,12 @@
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||
|
||||
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||
|
||||
"react-to-webcomponent": ["react-to-webcomponent@2.0.1", "", { "dependencies": { "@r2wc/core": "^1.0.0" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-jpVztcA0SbV6TnBRV6EFuU+hmuuSIxgEww3wRcbneT0ytqn57y9ygeRfUmhzz8+bYg53u1h4COKk8iAextHE+Q=="],
|
||||
|
||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
@@ -722,6 +745,8 @@
|
||||
|
||||
"sass-embedded-win32-x64": ["sass-embedded-win32-x64@1.92.1", "", { "os": "win32", "cpu": "x64" }, "sha512-B6Nz/GbH7Vkpb2TkQHsGcczWM5t+70VWopWF1x5V5yxLpA8ZzVQ7NTKKi+jDoVY2Efu6ZyzgT9n5KgG2kWliXA=="],
|
||||
|
||||
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||
|
||||
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||
|
||||
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
||||
@@ -730,6 +755,8 @@
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"sileo": ["sileo@0.1.3", "", { "dependencies": { "motion": "^12.34.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-kmGjM2ts2TpuPzOaD7llxcMpU37Pyj5dO8s4wGXvDlR143zV2sB6sJ76PCVP4kY2+hfkrLJhiSm/wXGdUHDFjQ=="],
|
||||
|
||||
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
@@ -33,7 +33,11 @@
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"lucide-svelte": "^0.562.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-to-webcomponent": "^2.0.1",
|
||||
"semver": "^7.7.2",
|
||||
"sileo": "^0.1.3",
|
||||
"svelte-confetti": "^2.3.2",
|
||||
"tw-animate-css": "^1.3.8"
|
||||
},
|
||||
@@ -48,6 +52,7 @@
|
||||
"@tauri-apps/cli": "^2.9.6",
|
||||
"@types/bun": "^1.2.21",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/semver": "^7.7.1",
|
||||
"autoprefixer": "10.4.21",
|
||||
"bits-ui": "^1.4.7",
|
||||
|
||||
+34
-57
@@ -56,17 +56,11 @@ pub fn valid_osu_folder(folder: String) -> bool {
|
||||
"scores.db",
|
||||
];
|
||||
|
||||
let folder_files: Vec<&str> = osu_folder_files.iter().map(|&s| s).collect();
|
||||
if folder_files.iter().any(|&file| file == "osu!.exe") == false {
|
||||
let path = PathBuf::from(folder);
|
||||
if !path.join("osu!.exe").exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let path = PathBuf::from(folder);
|
||||
let match_percentage = check_folder_completeness(path, &osu_folder_files) >= 70.0;
|
||||
if match_percentage {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
check_folder_completeness(path, &osu_folder_files) >= 70.0
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
@@ -160,7 +154,7 @@ pub fn find_osu_installation() -> Option<String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
||||
pub async fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
||||
let path = PathBuf::from(folder);
|
||||
let osu_user_config = get_osu_user_config(path.clone());
|
||||
let songs_path = osu_user_config
|
||||
@@ -173,12 +167,12 @@ pub fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
if let Ok(entries) = std::fs::read_dir(songs_folder) {
|
||||
for entry in entries.flatten() {
|
||||
if entry.file_type().map_or(false, |ft| ft.is_dir()) {
|
||||
if let Ok(mut entries) = fs::read_dir(songs_folder).await {
|
||||
while let Ok(Some(entry)) = entries.next_entry().await {
|
||||
if entry.file_type().await.map_or(false, |ft| ft.is_dir()) {
|
||||
let dir_path = entry.path();
|
||||
if let Ok(files) = std::fs::read_dir(&dir_path) {
|
||||
for file in files.flatten() {
|
||||
if let Ok(mut files) = fs::read_dir(&dir_path).await {
|
||||
while let Ok(Some(file)) = files.next_entry().await {
|
||||
if file.path().extension().map_or(false, |ext| ext == "osu") {
|
||||
count += 1;
|
||||
break;
|
||||
@@ -192,7 +186,7 @@ pub fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_skins_count(folder: String) -> Option<u64> {
|
||||
pub async fn get_skins_count(folder: String) -> Option<u64> {
|
||||
let path = PathBuf::from(folder);
|
||||
let skins_folder = path.join("Skins");
|
||||
|
||||
@@ -201,12 +195,12 @@ pub fn get_skins_count(folder: String) -> Option<u64> {
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
if let Ok(entries) = std::fs::read_dir(skins_folder) {
|
||||
for entry in entries.flatten() {
|
||||
if entry.file_type().map_or(false, |ft| ft.is_dir()) {
|
||||
if let Ok(mut entries) = fs::read_dir(skins_folder).await {
|
||||
while let Ok(Some(entry)) = entries.next_entry().await {
|
||||
if entry.file_type().await.map_or(false, |ft| ft.is_dir()) {
|
||||
let dir_path = entry.path();
|
||||
if let Ok(files) = std::fs::read_dir(&dir_path) {
|
||||
for file in files.flatten() {
|
||||
if let Ok(mut files) = fs::read_dir(&dir_path).await {
|
||||
while let Ok(Some(file)) = files.next_entry().await {
|
||||
if file.path().extension().map_or(false, |ext| ext == "ini") {
|
||||
count += 1;
|
||||
break;
|
||||
@@ -222,28 +216,28 @@ pub fn get_skins_count(folder: String) -> Option<u64> {
|
||||
#[tauri::command]
|
||||
pub fn get_osu_skin(folder: String) -> String {
|
||||
let path = PathBuf::from(folder);
|
||||
let osu_user_config = get_osu_user_config(path.clone());
|
||||
return osu_user_config
|
||||
let osu_user_config = get_osu_user_config(path);
|
||||
osu_user_config
|
||||
.and_then(|config| config.get("Skin").cloned())
|
||||
.unwrap_or_else(|| "Default".to_string());
|
||||
.unwrap_or_else(|| "Default".to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_osu_version(folder: String) -> String {
|
||||
let path = PathBuf::from(folder);
|
||||
let osu_user_config = get_osu_user_config(path.clone());
|
||||
return osu_user_config
|
||||
let osu_user_config = get_osu_user_config(path);
|
||||
osu_user_config
|
||||
.and_then(|config| config.get("LastVersion").cloned())
|
||||
.unwrap_or_else(|| "failed".to_string());
|
||||
.unwrap_or_else(|| "failed".to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_osu_release_stream(folder: String) -> String {
|
||||
let path = PathBuf::from(folder);
|
||||
let osu_config = get_osu_config(path.clone());
|
||||
return osu_config
|
||||
let osu_config = get_osu_config(path);
|
||||
osu_config
|
||||
.and_then(|config| config.get("_ReleaseStream").cloned())
|
||||
.unwrap_or_else(|| "Stable40".to_string());
|
||||
.unwrap_or_else(|| "Stable40".to_string())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
@@ -261,10 +255,7 @@ pub fn set_osu_user_config_values(
|
||||
.iter()
|
||||
.map(|entry| (entry.key.as_str(), Some(entry.value.as_str())))
|
||||
.collect();
|
||||
match set_osu_user_config_vals(&osu_folder_path, &converted) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(_) => Ok(false),
|
||||
}
|
||||
Ok(set_osu_user_config_vals(&osu_folder_path, &converted).is_ok())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -276,22 +267,16 @@ pub fn set_osu_config_values(
|
||||
.iter()
|
||||
.map(|entry| (entry.key.as_str(), Some(entry.value.as_str())))
|
||||
.collect();
|
||||
match set_osu_config_vals(&osu_folder_path, &converted) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(_) => Ok(false),
|
||||
}
|
||||
Ok(set_osu_config_vals(&osu_folder_path, &converted).is_ok())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn run_osu_updater(folder: String) -> Result<(), String> {
|
||||
#[cfg(windows)]
|
||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||
#[cfg(windows)]
|
||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
||||
|
||||
let mut updater_process = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
||||
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
||||
Command::new(&osu_exe_path)
|
||||
.arg("-repair")
|
||||
@@ -368,9 +353,6 @@ pub async fn run_osu_updater(folder: String) -> Result<(), String> {
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
||||
/* #[cfg(windows)]
|
||||
use std::os::windows::process::CommandExt; */
|
||||
|
||||
#[cfg(windows)]
|
||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||
#[cfg(windows)]
|
||||
@@ -385,7 +367,7 @@ pub async fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
||||
.arg("ez-pp.farm")
|
||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
||||
.spawn()
|
||||
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||
.map_err(|e| format!("Failed to spawn osu: {}", e))?
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
@@ -394,7 +376,7 @@ pub async fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
||||
.arg("--devserver")
|
||||
.arg("ez-pp.farm")
|
||||
.spawn()
|
||||
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||
.map_err(|e| format!("Failed to spawn osu: {}", e))?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -593,7 +575,7 @@ pub fn replace_ui_files(folder: String, revert: bool) -> Result<(), ReplaceUIErr
|
||||
if !revert {
|
||||
try_rename(&osu_ui, &osu_ui_bak)?;
|
||||
try_rename(&ezpp_ui, &osu_ui)?;
|
||||
|
||||
|
||||
try_rename(&osu_seasonal, &osu_seasonal_bak)?;
|
||||
try_rename(&ezpp_seasonal, &osu_seasonal)?;
|
||||
|
||||
@@ -602,7 +584,7 @@ pub fn replace_ui_files(folder: String, revert: bool) -> Result<(), ReplaceUIErr
|
||||
} else {
|
||||
try_rename(&osu_ui, &ezpp_ui)?;
|
||||
try_rename(&osu_ui_bak, &osu_ui)?;
|
||||
|
||||
|
||||
try_rename(&osu_seasonal, &ezpp_seasonal)?;
|
||||
try_rename(&osu_seasonal_bak, &osu_seasonal)?;
|
||||
|
||||
@@ -732,12 +714,7 @@ pub async fn has_net8() -> bool {
|
||||
|
||||
#[tauri::command]
|
||||
pub fn encrypt_string(string: String, entropy: String) -> String {
|
||||
let encrypted = encrypt_password(&string, &entropy);
|
||||
|
||||
match encrypted {
|
||||
Ok(encrypted_vec) => encrypted_vec,
|
||||
Err(_) => string,
|
||||
}
|
||||
encrypt_password(&string, &entropy).unwrap_or(string)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -773,7 +750,7 @@ pub async fn download_ezpp_launcher_update(app: AppHandle, url: String) -> Resul
|
||||
UpdateStatus {
|
||||
file_name: "Update".to_string(),
|
||||
downloaded,
|
||||
size: size,
|
||||
size,
|
||||
progress: ((downloaded as f64 / size as f64 * 100.0) * 100.0).trunc() / 100.0,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { createElement } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import type { SileoOptions } from 'sileo'
|
||||
|
||||
let props: SileoOptions = $props()
|
||||
let rootEl: HTMLElement
|
||||
|
||||
$effect(() => {
|
||||
const root = createRoot(rootEl)
|
||||
|
||||
import('sileo').then(({ Toaster }) => {
|
||||
const sileo = createElement(Toaster, { ...props })
|
||||
root.render(sileo)
|
||||
})
|
||||
|
||||
return () => root.unmount()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={rootEl}></div>
|
||||
+3
-1
@@ -3,7 +3,7 @@ import type { UpdateFile, UpdateStatus } from './types';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import { betterFetch } from '@better-fetch/fetch';
|
||||
|
||||
const updateUrl = 'https://next.ez-pp.farm/api/ezpplauncher';
|
||||
const updateUrl = 'https://ez-pp.farm/api/ezpplauncher';
|
||||
|
||||
export const getHWID = async () => {
|
||||
const hwid = await invoke('get_hwid');
|
||||
@@ -83,6 +83,8 @@ export const getEZPPLauncherStreams = async () => {
|
||||
return resp.data.streams;
|
||||
}
|
||||
|
||||
console.log(resp.error);
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
userSettings,
|
||||
} from '@/userSettings';
|
||||
import { Buffer } from 'buffer';
|
||||
import { Toaster } from '@/components/ui/sonner';
|
||||
import SileoToast from '@/components/ui/sileo/sileo-toast.svelte';
|
||||
import { userAuth } from '@/userAuthentication';
|
||||
import { encryptString, exit, getLauncherVersion, getPlatform } from '@/osuUtil';
|
||||
import Button from '@/components/ui/button/button.svelte';
|
||||
@@ -150,7 +150,7 @@
|
||||
<OsuCursor smoothCursor={$cursorSmoothening} />
|
||||
{/if}
|
||||
|
||||
<Toaster richColors closeButton theme="dark" position="top-right" />
|
||||
<SileoToast position="top-center" fill="black" />
|
||||
|
||||
<Titlebar />
|
||||
|
||||
|
||||
+115
-22
@@ -64,7 +64,6 @@
|
||||
} from '@/userSettings';
|
||||
import Input from '@/components/ui/input/input.svelte';
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { currentUser, userAuth } from '@/userAuthentication';
|
||||
import {
|
||||
getGamemodeInt,
|
||||
@@ -109,6 +108,7 @@
|
||||
import DownloadButton from '@/components/ui/download-button/DownloadButton.svelte';
|
||||
import { animate } from 'animejs';
|
||||
import AnimatedBg from '@/components/ui/animated-bg/AnimatedBg.svelte';
|
||||
import { sileo } from 'sileo';
|
||||
|
||||
let selectedView = $state('home');
|
||||
let progress = $state(-1);
|
||||
@@ -146,16 +146,28 @@
|
||||
}
|
||||
const validFolder = await isValidOsuFolder(selectedPath);
|
||||
if (!validFolder) {
|
||||
toast.error('Oops...', {
|
||||
sileo.error({
|
||||
title: 'Hmm...',
|
||||
description:
|
||||
'The selected folder is not a valid osu! installation folder. Please select the correct folder.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
osuInstallationPath.set(selectedPath);
|
||||
$userSettings.value('osu_installation_path').set(selectedPath);
|
||||
$userSettings.save();
|
||||
toast.success('osu! installation path set successfully.');
|
||||
sileo.success({
|
||||
title: 'Yay!',
|
||||
description: 'osu! installation path set successfully.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
|
||||
const beatmapSetCount: number | null = await getBeatmapSetsCount(selectedPath);
|
||||
if (beatmapSetCount) beatmapSets.set(beatmapSetCount);
|
||||
@@ -178,15 +190,25 @@
|
||||
if ($trackingEnabled) umami.track('app_launch_osu');
|
||||
const osuRunning = await isOsuRunning();
|
||||
if (osuRunning) {
|
||||
toast.error('Hold on a second!', {
|
||||
sileo.error({
|
||||
title: 'Hold on a second!',
|
||||
description:
|
||||
'osu! is currently running, please exit osu! before launching via EZPPLauncher!',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!$osuBuild) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'There was an issue detecting your installed osu! version',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -197,8 +219,13 @@
|
||||
|
||||
const validFolder = await isValidOsuFolder(osuPath);
|
||||
if (!validFolder) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'Your selected osu! installation folder is not valid.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
@@ -206,15 +233,25 @@
|
||||
|
||||
if ($platform === 'linux') {
|
||||
if (!(await hasWMCTRL())) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'wmctrl seems to be missing, please install via AUR.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
}
|
||||
if (!(await hasOsuWinello())) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'osu-winello seems to be missing, please install it.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
@@ -258,8 +295,13 @@
|
||||
try {
|
||||
const streamInfo = await osuapi.latestBuildVersion('stable40');
|
||||
if (!streamInfo) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'Failed to check for updates, maybe osu! is down?',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
@@ -268,8 +310,13 @@
|
||||
const releaseStream = await getReleaseStream(osuPath);
|
||||
|
||||
if (releaseStream === undefined) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'Failed to get osu! release stream.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
@@ -277,8 +324,13 @@
|
||||
|
||||
// only stable osu! release streams are supported for now
|
||||
if (!releaseStream.toLowerCase().includes('stable')) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'You are not on the stable release stream, please switch to it.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
return;
|
||||
@@ -531,8 +583,13 @@
|
||||
cleanup = false;
|
||||
const error = err as Error;
|
||||
if (error.name === 'AbortError') {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'Failed to launch.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
launchError = {
|
||||
@@ -541,8 +598,13 @@
|
||||
};
|
||||
} else {
|
||||
launchError = error;
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'Failed to launch.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
launching.set(false);
|
||||
if ($trackingEnabled) umami.track('app_launch_fail', { error: err });
|
||||
@@ -560,8 +622,13 @@
|
||||
try {
|
||||
const loginResult = await ezppfarm.login(username, password);
|
||||
if (loginResult && loginResult.user) {
|
||||
toast.success('Login successful!', {
|
||||
sileo.success({
|
||||
title: 'Login successful!',
|
||||
description: `Welcome back, ${loginResult.user.name}!`,
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
|
||||
$userAuth.value('username').set(username);
|
||||
@@ -571,14 +638,24 @@
|
||||
currentUser.set(loginResult.user);
|
||||
selectedView = 'home';
|
||||
} else {
|
||||
toast.error('Login failed!', {
|
||||
sileo.error({
|
||||
title: 'Login failed!',
|
||||
description: 'Please check your username and password.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
loginIsLoading = false;
|
||||
}
|
||||
} catch {
|
||||
toast.error('Server error occurred during login.', {
|
||||
sileo.error({
|
||||
title: 'Login failed!',
|
||||
description: 'There was an issue connecting to the server. Please try again later.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
loginIsLoading = false;
|
||||
}
|
||||
@@ -706,8 +783,13 @@
|
||||
onclick={async () => {
|
||||
const updateFile = $newVersion?.assets.find((asset) => asset.name.endsWith('.exe'));
|
||||
if (!updateFile) {
|
||||
toast.error('Hmmm...', {
|
||||
sileo.error({
|
||||
title: 'Hmmm...',
|
||||
description: 'No update file found.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
$newVersion = undefined;
|
||||
return;
|
||||
@@ -836,8 +918,13 @@
|
||||
$userAuth.value('username').del();
|
||||
$userAuth.value('password').del();
|
||||
await $userAuth.save();
|
||||
toast.success('Logout successful!', {
|
||||
sileo.success({
|
||||
title: 'Logout successful!',
|
||||
description: 'See you soon!',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
currentUser.set(undefined);
|
||||
currentUserInfo.set(undefined);
|
||||
@@ -1289,11 +1376,17 @@
|
||||
bind:value={$launcherStream}
|
||||
onValueChange={async (newStream) => {
|
||||
const isNet8Installed = await hasNet8();
|
||||
if (newStream === 'experimental' && !isNet8Installed) {
|
||||
if (!isNet8Installed) {
|
||||
launcherStream.set('stable');
|
||||
toast.error('.NET 8.0 Desktop Runtime not found!', {
|
||||
action: {
|
||||
label: 'Download .NET 8.0',
|
||||
sileo.error({
|
||||
title: 'Hmm...',
|
||||
description: '.NET 8.0 Desktop Runtime not found!',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
button: {
|
||||
title: 'Download .NET 8.0',
|
||||
onClick: async () =>
|
||||
await openURL(
|
||||
'https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.22-windows-x64-installer'
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
import Launch from './Launch.svelte';
|
||||
import { currentUser, userAuth } from '@/userAuthentication';
|
||||
import { ezppfarm } from '@/api/ezpp';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { currentUserInfo } from '@/data';
|
||||
import {
|
||||
getBeatmapSetsCount,
|
||||
@@ -40,6 +39,7 @@
|
||||
isValidOsuFolder,
|
||||
} from '@/osuUtil';
|
||||
import { git } from '@/api/git';
|
||||
import { sileo } from 'sileo';
|
||||
|
||||
let ezppLogo: HTMLImageElement;
|
||||
let spinnerCircle: SVGCircleElement;
|
||||
@@ -89,19 +89,34 @@
|
||||
try {
|
||||
const loginResult = await ezppfarm.login(username, password);
|
||||
if (loginResult && loginResult.user) {
|
||||
toast.success('Login successful!', {
|
||||
sileo.success({
|
||||
title: 'Login successful!',
|
||||
description: `Welcome back, ${loginResult.user.name}!`,
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
|
||||
currentUser.set(loginResult.user);
|
||||
} else {
|
||||
toast.error('Login failed!', {
|
||||
sileo.error({
|
||||
title: 'Login failed!',
|
||||
description: 'Please check your username and password.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
toast.error('Server error occurred during login.', {
|
||||
sileo.error({
|
||||
title: 'Login failed!',
|
||||
description: 'There was an issue connecting to the server. Please try again later.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -123,8 +138,13 @@
|
||||
osuInstallationPath.set('');
|
||||
$userSettings.value('osu_installation_path').del();
|
||||
await $userSettings.save();
|
||||
toast.error('Oops...', {
|
||||
sileo.error({
|
||||
title: 'Hmm...',
|
||||
description: 'Your previously set osu! installation path seems to be invalid.',
|
||||
fill: '#181825',
|
||||
styles: {
|
||||
description: 'text-center!',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
currentLoadingInfo.set('Getting osu version...');
|
||||
|
||||
Reference in New Issue
Block a user