Compare commits

...
1 Commits
Author SHA1 Message Date
AxTps 13a56f4200 fix: Linux 系统安装时游戏目录默认回退到用户主目录
Sync source to CNB / Sync Git ref (push) Skipped
从 deb 等系统包安装时,启动器可执行文件位于 /usr/bin,此前一键安装
StarLight 实例的"选择游戏目录"弹窗会默认到这个系统目录,普通用户既
无写权限,也不适合存放游戏数据。

将默认目录计算移入 theseus::default_game_dir_root():Linux 下若可执行
文件位于 /usr、/opt、/snap 等系统路径,回退到用户主目录;便携版与其
他平台仍使用可执行文件所在目录。
2026-10-17 16:12:28 +08:00
3 changed files with 32 additions and 6 deletions

No files matched your search

+2 -5
View File
@@ -324,12 +324,9 @@ async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
/// external game-directory root for the one-click StarLight install flow. /// external game-directory root for the one-click StarLight install flow.
#[tauri::command] #[tauri::command]
fn get_launcher_root_dir() -> api::Result<String> { fn get_launcher_root_dir() -> api::Result<String> {
let exe = std::env::current_exe().map_err(|error| { let dir = theseus::default_game_dir_root().ok_or_else(|| {
theseus::Error::from(theseus::ErrorKind::FSError(error.to_string()))
})?;
let dir = exe.parent().ok_or_else(|| {
theseus::Error::from(theseus::ErrorKind::FSError( theseus::Error::from(theseus::ErrorKind::FSError(
"Launcher executable has no parent directory".to_string(), "Could not determine a default game directory root".to_string(),
)) ))
})?; })?;
Ok(dir.to_string_lossy().into_owned()) Ok(dir.to_string_lossy().into_owned())
+1 -1
View File
@@ -39,7 +39,7 @@ pub use state::{DirectoryInfo, State};
pub use storage::*; pub use storage::*;
pub use util::fetch::build_proxied_client; pub use util::fetch::build_proxied_client;
pub use util::file_lock::{LockingProcess, get_locking_processes}; pub use util::file_lock::{LockingProcess, get_locking_processes};
pub use util::platform::is_process_elevated; pub use util::platform::{default_game_dir_root, is_process_elevated};
pub use util::proxy::{ProxyConfig, ProxyMode, ProxyTestResult}; pub use util::proxy::{ProxyConfig, ProxyMode, ProxyTestResult};
pub use util::symlink::SymlinkCapability; pub use util::symlink::SymlinkCapability;
+29
View File
@@ -1,5 +1,6 @@
//! Platform-related code //! Platform-related code
use daedalus::minecraft::{Os, OsRule}; use daedalus::minecraft::{Os, OsRule};
use std::path::PathBuf;
/// (e.g. "Run as administrator" on Windows). /// (e.g. "Run as administrator" on Windows).
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@@ -143,3 +144,31 @@ pub fn classpath_separator(java_arch: &str) -> &'static str {
Os::Windows | Os::WindowsArm64 => ";", Os::Windows | Os::WindowsArm64 => ";",
} }
} }
/// Root directory used as the default for one-click StarLight instance
/// installs. Portable builds live next to their executable, which is a fine
/// place for game data. System installs (e.g. a Linux `.deb` under `/usr/bin`)
/// do not, so fall back to the user's home directory there.
pub fn default_game_dir_root() -> Option<PathBuf> {
let exe_dir = std::env::current_exe().ok()?.parent()?.to_path_buf();
if cfg!(target_os = "linux") && is_system_install_dir(&exe_dir) {
return dirs::home_dir();
}
Some(exe_dir)
}
#[cfg(target_os = "linux")]
fn is_system_install_dir(path: &std::path::Path) -> bool {
const SYSTEM_PREFIXES: &[&str] = &[
"/usr/", "/opt/", "/snap/", "/bin/", "/sbin/", "/lib/", "/lib64/",
];
let display = path.to_string_lossy();
SYSTEM_PREFIXES
.iter()
.any(|prefix| display.starts_with(prefix))
}
#[cfg(not(target_os = "linux"))]
fn is_system_install_dir(_path: &std::path::Path) -> bool {
false
}