[code][fix] improvements for LAN 202503
- more robust client <-> server connection - new client event: DownloadGameFilesFailed - 3 seconds to reconnect - retry forever if server is gone and never lose a UI request - code cleanup here and there (mostly server)
This commit is contained in:
@ -21,7 +21,7 @@ struct LanSpreadState {
|
||||
client_ctrl: UnboundedSender<ClientCommand>,
|
||||
games: Arc<Mutex<GameDB>>,
|
||||
games_in_download: Arc<Mutex<HashSet<String>>>,
|
||||
games_dir: Arc<Mutex<String>>,
|
||||
games_folder: Arc<Mutex<String>>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@ -35,11 +35,9 @@ fn request_games(state: tauri::State<LanSpreadState>) {
|
||||
|
||||
#[tauri::command]
|
||||
fn install_game(id: String, state: tauri::State<LanSpreadState>) -> bool {
|
||||
log::error!("Running game with id {id}");
|
||||
|
||||
let already_in_download = tauri::async_runtime::block_on(async {
|
||||
if state.inner().games_in_download.lock().await.contains(&id) {
|
||||
log::error!("Game is already downloading: {id}");
|
||||
log::warn!("Game is already downloading: {id}");
|
||||
return true;
|
||||
}
|
||||
false
|
||||
@ -62,16 +60,16 @@ fn run_game(id: String, state: tauri::State<LanSpreadState>) {
|
||||
|
||||
log::error!("run_game {id}");
|
||||
|
||||
let games_dir =
|
||||
tauri::async_runtime::block_on(async { state.inner().games_dir.lock().await.clone() });
|
||||
let games_folder =
|
||||
tauri::async_runtime::block_on(async { state.inner().games_folder.lock().await.clone() });
|
||||
|
||||
let games_dir = PathBuf::from(games_dir);
|
||||
if !games_dir.exists() {
|
||||
log::error!("games_dir {games_dir:?} does not exist");
|
||||
let games_folder = PathBuf::from(games_folder);
|
||||
if !games_folder.exists() {
|
||||
log::error!("games_folder {games_folder:?} does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
let game_path = games_dir.join(id);
|
||||
let game_path = games_folder.join(id);
|
||||
|
||||
let game_setup_bin = game_path.join("game_setup.cmd");
|
||||
let game_start_bin = game_path.join("game_start.cmd");
|
||||
@ -84,7 +82,7 @@ fn run_game(id: String, state: tauri::State<LanSpreadState>) {
|
||||
{
|
||||
log::error!("failed to run game_setup.cmd: {e}");
|
||||
return;
|
||||
} else if let Err(e) = std::fs::File::create(FIRST_START_DONE_FILE) {
|
||||
} else if let Err(e) = File::create(FIRST_START_DONE_FILE) {
|
||||
log::error!("failed to create {first_start_done_file:?}: {e}");
|
||||
}
|
||||
}
|
||||
@ -104,7 +102,7 @@ fn set_game_install_state_from_path(game_db: &mut GameDB, path: &Path, installed
|
||||
if let Some(file_name) = file_name.to_str() {
|
||||
if let Some(game) = game_db.get_mut_game_by_id(file_name) {
|
||||
if installed {
|
||||
log::info!("Game is installed: {game}");
|
||||
log::debug!("Game is installed: {game}");
|
||||
} else {
|
||||
log::error!("Game is missing: {game}");
|
||||
}
|
||||
@ -126,14 +124,14 @@ fn update_game_directory(app_handle: tauri::AppHandle, path: String) {
|
||||
|
||||
{
|
||||
tauri::async_runtime::block_on(async {
|
||||
let mut games_dir = app_handle
|
||||
let mut games_folder = app_handle
|
||||
.state::<LanSpreadState>()
|
||||
.inner()
|
||||
.games_dir
|
||||
.games_folder
|
||||
.lock()
|
||||
.await;
|
||||
|
||||
*games_dir = path.clone();
|
||||
*games_folder = path.clone();
|
||||
});
|
||||
}
|
||||
|
||||
@ -167,7 +165,7 @@ fn update_game_directory(app_handle: tauri::AppHandle, path: String) {
|
||||
if let Ok(path_type) = entry.file_type() {
|
||||
if path_type.is_dir() {
|
||||
let path = entry.path();
|
||||
if path.join(".softlan_game_installed").exists() {
|
||||
if path.join("version.ini").exists() {
|
||||
set_game_install_state_from_path(&mut game_db, &path, true);
|
||||
}
|
||||
}
|
||||
@ -249,9 +247,13 @@ async fn do_unrar(sidecar: Command, rar_file: &Path, dest_dir: &Path) -> eyre::R
|
||||
.to_str()
|
||||
.ok_or_else(|| eyre::eyre!("failed to get str of dest_dir"))?;
|
||||
|
||||
log::error!("SIDECARE: {:?}", &sidecar);
|
||||
log::info!(
|
||||
"unrar game: {} to {}",
|
||||
rar_file.canonicalize()?.display(),
|
||||
dest_dir
|
||||
);
|
||||
|
||||
sidecar
|
||||
let out = sidecar
|
||||
.arg("x") // extract files
|
||||
.arg(rar_file.canonicalize()?)
|
||||
.arg("-y") // Assume Yes on all queries
|
||||
@ -260,6 +262,10 @@ async fn do_unrar(sidecar: Command, rar_file: &Path, dest_dir: &Path) -> eyre::R
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !out.status.success() {
|
||||
log::error!("unrar stderr: {}", String::from_utf8_lossy(&out.stderr));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
log::error!("dest_dir canonicalize failed: {:?}", &dest_dir);
|
||||
@ -274,20 +280,13 @@ async fn do_unrar(sidecar: Command, rar_file: &Path, dest_dir: &Path) -> eyre::R
|
||||
bail!("failed to create directory: {dest_dir:?}");
|
||||
}
|
||||
|
||||
async fn unpack_game(id: &str, sidecar: Command, games_dir: String) {
|
||||
let game_path = PathBuf::from(games_dir).join(id);
|
||||
async fn unpack_game(id: &str, sidecar: Command, games_folder: String) {
|
||||
let game_path = PathBuf::from(games_folder).join(id);
|
||||
let eti_rar = game_path.join(format!("{id}.eti"));
|
||||
let local_path = game_path.join("local");
|
||||
|
||||
if let Err(e) = do_unrar(sidecar, &eti_rar, &local_path).await {
|
||||
log::error!("{eti_rar:?} -> {local_path:?}: {e}");
|
||||
} else {
|
||||
let game_installed_file = game_path.join(".softlan_game_installed");
|
||||
if let Err(e) = File::create(game_installed_file) {
|
||||
log::error!("failed to create game_installed_file: {e}");
|
||||
} else {
|
||||
log::info!("game unpacked: {id}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,8 +298,6 @@ pub fn run() {
|
||||
tauri_plugin_log::TargetKind::Stdout,
|
||||
))
|
||||
.level(log::LevelFilter::Info)
|
||||
.level_for("lanspread_client", log::LevelFilter::Debug)
|
||||
.level_for("lanspread_tauri_leptos_lib", log::LevelFilter::Debug)
|
||||
.level_for("mdns_sd::service_daemon", log::LevelFilter::Off);
|
||||
|
||||
// channel to pass commands to the client
|
||||
@ -316,7 +313,7 @@ pub fn run() {
|
||||
client_ctrl: tx_client_control,
|
||||
games: Arc::new(Mutex::new(GameDB::empty())),
|
||||
games_in_download: Arc::new(Mutex::new(HashSet::new())),
|
||||
games_dir: Arc::new(Mutex::new("".to_string())),
|
||||
games_folder: Arc::new(Mutex::new("".to_string())),
|
||||
};
|
||||
|
||||
tauri::Builder::default()
|
||||
@ -347,13 +344,12 @@ pub fn run() {
|
||||
log::info!("ClientEvent::ListGames received");
|
||||
update_game_db(games, app_handle.clone()).await;
|
||||
}
|
||||
ClientEvent::GotGameFiles(game_file_descs) => {
|
||||
ClientEvent::GotGameFiles { id, file_descriptions } => {
|
||||
log::info!("ClientEvent::GotGameFiles received");
|
||||
|
||||
if let Some(first_desc_file) = game_file_descs.first() {
|
||||
if let Err(e) = app_handle.emit(
|
||||
"game-download-pre",
|
||||
Some(first_desc_file.game_id.clone()),
|
||||
Some(id.clone()),
|
||||
) {
|
||||
log::error!("ClientEvent::GotGameFiles: Failed to emit game-download-pre event: {e}");
|
||||
}
|
||||
@ -362,11 +358,12 @@ pub fn run() {
|
||||
.state::<LanSpreadState>()
|
||||
.inner()
|
||||
.client_ctrl
|
||||
.send(ClientCommand::DownloadGameFiles(game_file_descs))
|
||||
.send(ClientCommand::DownloadGameFiles{
|
||||
id,
|
||||
file_descriptions,
|
||||
})
|
||||
.unwrap();
|
||||
} else {
|
||||
log::error!("ClientEvent::GotGameFiles: Got empty game files list");
|
||||
}
|
||||
|
||||
}
|
||||
ClientEvent::DownloadGameFilesBegin { id } => {
|
||||
log::info!("ClientEvent::DownloadGameFilesBegin received");
|
||||
@ -398,16 +395,16 @@ pub fn run() {
|
||||
.remove(&id.clone());
|
||||
|
||||
|
||||
let games_dir = app_handle
|
||||
let games_folder = app_handle
|
||||
.state::<LanSpreadState>()
|
||||
.inner()
|
||||
.games_dir
|
||||
.games_folder
|
||||
.lock()
|
||||
.await
|
||||
.clone();
|
||||
|
||||
if let Ok(sidecar) = app_handle.shell().sidecar("unrar") {
|
||||
unpack_game(&id, sidecar, games_dir).await;
|
||||
unpack_game(&id, sidecar, games_folder).await;
|
||||
|
||||
log::info!("ClientEvent::UnpackGameFinished received");
|
||||
if let Err(e) = app_handle.emit("game-unpack-finished", Some(id.clone())) {
|
||||
@ -415,6 +412,21 @@ pub fn run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientEvent::DownloadGameFilesFailed { id } => {
|
||||
log::warn!("ClientEvent::DownloadGameFilesFailed received");
|
||||
|
||||
if let Err(e) = app_handle.emit("game-download-failed", Some(id.clone())) {
|
||||
log::error!("Failed to emit game-download-failed event: {e}");
|
||||
}
|
||||
|
||||
app_handle
|
||||
.state::<LanSpreadState>()
|
||||
.inner()
|
||||
.games_in_download
|
||||
.lock()
|
||||
.await
|
||||
.remove(&id.clone());
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user