feat(install): write launcher language marker files

Some games include a language.txt marker in the unpacked local tree, similar
in spirit to account_name.txt. Installs and updates now carry the launcher
language alongside the account name so those game-provided marker files are
rewritten before staged files are promoted into local/.

The Tauri command boundary keeps the UI setting vocabulary as de/en, then maps
it to the file vocabulary expected by games: german or english. Unknown values
continue through the existing DEFAULT_LANGUAGE path, so the marker file falls
back to english just like script launch arguments fall back to en.

The transaction layer deliberately reuses the same first-match traversal helper
for both marker files. The searches stay independent, so games may place
account_name.txt and language.txt in different directories if their archive
layout requires that.

Test Plan:
- just fmt
- just test
- just frontend-test
- just clippy
- deno task build
- git diff --check

Refs: none
This commit is contained in:
2026-05-21 22:24:59 +02:00
parent e06a887da1
commit 9bafd981d7
7 changed files with 162 additions and 56 deletions
+13 -2
View File
@@ -230,6 +230,7 @@ pub enum PeerCommand {
id: String,
file_descriptions: Vec<GameFileDescription>,
account_name: Option<String>,
language: Option<String>,
},
/// Download game files with an explicit install policy.
DownloadGameFilesWithOptions {
@@ -237,11 +238,13 @@ pub enum PeerCommand {
file_descriptions: Vec<GameFileDescription>,
install_after_download: bool,
account_name: Option<String>,
language: Option<String>,
},
/// Install already-downloaded archives into `local/`.
InstallGame {
id: String,
account_name: Option<String>,
language: Option<String>,
},
/// Remove only the `local/` install for a game.
UninstallGame { id: String },
@@ -411,6 +414,7 @@ async fn handle_peer_commands(
id,
file_descriptions,
account_name,
language,
} => {
handle_download_game_files_command(
ctx,
@@ -419,6 +423,7 @@ async fn handle_peer_commands(
file_descriptions,
true,
account_name,
language,
)
.await;
}
@@ -427,6 +432,7 @@ async fn handle_peer_commands(
file_descriptions,
install_after_download,
account_name,
language,
} => {
handle_download_game_files_command(
ctx,
@@ -435,11 +441,16 @@ async fn handle_peer_commands(
file_descriptions,
install_after_download,
account_name,
language,
)
.await;
}
PeerCommand::InstallGame { id, account_name } => {
handle_install_game_command(ctx, tx_notify_ui, id, account_name).await;
PeerCommand::InstallGame {
id,
account_name,
language,
} => {
handle_install_game_command(ctx, tx_notify_ui, id, account_name, language).await;
}
PeerCommand::UninstallGame { id } => {
handle_uninstall_game_command(ctx, tx_notify_ui, id).await;