From cf25a7f91fcc0dcb2d65327a6c391567f4256768 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 28 Apr 2025 22:58:51 -0400 Subject: [PATCH] Remove more launcher-only functions from Physis These are now being moved to the separate Miscel library that can be used standalone with Astra. --- src/execlookup.rs | 63 ------------ src/existing_dirs.rs | 239 ------------------------------------------- src/lib.rs | 6 -- 3 files changed, 308 deletions(-) delete mode 100644 src/execlookup.rs delete mode 100644 src/existing_dirs.rs diff --git a/src/execlookup.rs b/src/execlookup.rs deleted file mode 100644 index b0fdb8d..0000000 --- a/src/execlookup.rs +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Joshua Goins -// SPDX-License-Identifier: GPL-3.0-or-later - -use std::fs; - -fn from_u16(from: &mut [u16]) -> &[u8] { - #[cfg(target_endian = "little")] - from.iter_mut().for_each(|word| *word = word.to_be()); - - let ptr: *const u8 = from.as_ptr().cast(); - let len = from.len().checked_mul(2).unwrap(); - - unsafe { std::slice::from_raw_parts(ptr, len) } -} - -fn find_needle(installer_file: &[u8], needle: &str) -> Option { - let mut needle: Vec = needle.encode_utf16().collect(); - let bytes = from_u16(&mut needle); - - let mut position = installer_file - .windows(bytes.len()) - .position(|window| window == bytes)?; - - let parse_char_at_position = |position: usize| { - let upper = installer_file[position]; - let lower = installer_file[position + 1]; - - let result = char::decode_utf16([((upper as u16) << 8) | lower as u16]) - .map(|r| r.map_err(|e| e.unpaired_surrogate())) - .collect::>(); - - result[0] - }; - - let mut string: String = String::new(); - - let mut last_char = parse_char_at_position(position); - while last_char.is_ok() && last_char.unwrap() != '\0' { - string.push(last_char.unwrap()); - - position += 2; - last_char = parse_char_at_position(position); - } - - Some(string) -} - -/// Extract the frontier URL from ffxivlauncher.exe -pub fn extract_frontier_url(launcher_path: &str) -> Option { - let installer_file = fs::read(launcher_path).unwrap(); - - // New Frontier URL format - if let Some(url) = find_needle(&installer_file, "https://launcher.finalfantasyxiv.com") { - return Some(url); - } - - // Old Frontier URL format - if let Some(url) = find_needle(&installer_file, "https://frontier.ffxiv.com") { - return Some(url); - } - - None -} diff --git a/src/existing_dirs.rs b/src/existing_dirs.rs deleted file mode 100644 index 8aeacab..0000000 --- a/src/existing_dirs.rs +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Joshua Goins -// SPDX-License-Identifier: GPL-3.0-or-later - -// Rust deprecating this is stupid, I don't want to use a crate here -#[allow(deprecated)] -use std::env::home_dir; - -use std::fs; -use std::fs::read_dir; -use std::path::PathBuf; - -/// Where the existing installation came from -#[derive(Clone, Copy)] -#[repr(C)] -pub enum ExistingInstallType { - /// Installed via the official launcher - OfficialLauncher, - /// Installed via XIVQuickLauncher - XIVQuickLauncher, - /// Installed via XIVLauncherCore - XIVLauncherCore, - /// Installed via XIVOnMac - XIVOnMac, - /// Installed via Astra - Astra, -} - -/// An existing install location on disk -pub struct ExistingGameDirectory { - /// The application where this installation was from - pub install_type: ExistingInstallType, - /// The path to the "main folder" where "game" and "boot" sits - pub path: String, -} - -/// Finds existing installations on disk. Will only return locations that actually have files in them, and a really basic check to see if the data is valid. -pub fn find_existing_game_dirs() -> Vec { - let mut install_dirs = Vec::new(); - - match std::env::consts::OS { - "linux" => { - // Official install (Wine) - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir(".wine/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn") - }); - - // Official install (Steam) - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir( - ".steam/steam/steamapps/common/FINAL FANTASY XIV - A Realm Reborn", - ), - }); - - // XIVLauncherCore location - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::XIVLauncherCore, - path: from_home_dir(".xlcore/ffxiv"), - }); - - // Astra location. But we have to iterate through each UUID. - if let Ok(entries) = read_dir(from_home_dir(".local/share/astra/game/")) { - entries - .flatten() - .flat_map(|entry| { - let Ok(meta) = entry.metadata() else { - return vec![]; - }; - if meta.is_dir() { - return vec![entry.path()]; - } - vec![] - }) - .for_each(|path| { - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::Astra, - path: path.into_os_string().into_string().unwrap(), - }) - }); - } - } - "macos" => { - // Official Launcher (macOS) - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir("Library/Application Support/FINAL FANTASY XIV ONLINE/Bottles/published_Final_Fantasy/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn") - }); - - // TODO: add XIV on Mac - } - "windows" => { - // Official install (Wine) - install_dirs.push(ExistingGameDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn" - .parse() - .unwrap(), - }); - - // TODO: Add Astra - } - &_ => {} - } - - install_dirs - .into_iter() - .filter(|dir| is_valid_game_dir(&dir.path)) - .collect() -} - -/// An existing user directory -pub struct ExistingUserDirectory { - /// The application where this directory was from - pub install_type: ExistingInstallType, - /// The path to the user folder - pub path: String, -} - -/// Finds existing user folders on disk. Will only return locations that actually have files in them, and a really basic check to see if the data is valid. -pub fn find_existing_user_dirs() -> Vec { - let mut user_dirs = Vec::new(); - #[allow(deprecated)] // We still want std::env::home_dir - let Some(_) = home_dir() else { - return user_dirs; - }; - - match std::env::consts::OS { - "linux" => { - // Official install (Wine) - user_dirs.push(ExistingUserDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir("Documents/My Games/FINAL FANTASY XIV - A Realm Reborn"), - }); - - // XIVLauncherCore location - user_dirs.push(ExistingUserDirectory { - install_type: ExistingInstallType::XIVLauncherCore, - path: from_home_dir(".xlcore/ffxivConfig"), - }); - - // Astra location. But we have to iterate through each UUID. - if let Ok(entries) = read_dir(from_home_dir(".local/share/astra/user/")) { - entries - .flatten() - .flat_map(|entry| { - let Ok(meta) = entry.metadata() else { - return vec![]; - }; - if meta.is_dir() { - return vec![entry.path()]; - } - vec![] - }) - .for_each(|path| { - user_dirs.push(ExistingUserDirectory { - install_type: ExistingInstallType::Astra, - path: path.into_os_string().into_string().unwrap(), - }) - }); - } - } - "macos" => { - // Official install (Wine) - user_dirs.push(ExistingUserDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir("Documents/My Games/FINAL FANTASY XIV - A Realm Reborn"), - }) - - // TODO: Add XIV on Mac? - } - "windows" => { - // Official install - user_dirs.push(ExistingUserDirectory { - install_type: ExistingInstallType::OfficialLauncher, - path: from_home_dir("Documents/My Games/FINAL FANTASY XIV - A Realm Reborn"), - }) - - // TODO: Add Astra - } - &_ => {} - } - - user_dirs - .into_iter() - .filter(|dir| is_valid_user_dir(&dir.path)) - .collect() -} - -fn from_home_dir(path: &'static str) -> String { - #[allow(deprecated)] // We still want std::env::home_dir - let mut new_path = home_dir().unwrap(); - new_path.push(path); - new_path.into_os_string().into_string().unwrap() -} - -fn is_valid_game_dir(path: &String) -> bool { - let mut d = PathBuf::from(path); - - // Check for the dir itself - if fs::metadata(d.as_path()).is_err() { - return false; - } - - // Check for "game" - d.push("game"); - - if fs::metadata(d.as_path()).is_err() { - return false; - } - - // Check for "boot" - d.pop(); - d.push("boot"); - - if fs::metadata(d.as_path()).is_err() { - return false; - } - - true -} - -fn is_valid_user_dir(path: &String) -> bool { - let mut d = PathBuf::from(path); - - // Check for the dir itself - if fs::metadata(d.as_path()).is_err() { - return false; - } - - // Check for "FFXIV.cfg" - d.push("FFXIV.cfg"); - - if fs::metadata(d.as_path()).is_err() { - return false; - } - - true -} diff --git a/src/lib.rs b/src/lib.rs index 7889d8d..05d2965 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,9 +89,6 @@ pub mod layer; pub mod tera; -/// Reading data from executables -pub mod execlookup; - mod common_file_operations; /// Reading word dictionaries, such as the vulgar word list. @@ -136,9 +133,6 @@ pub mod avfx; /// Reading STM files pub mod stm; -/// Find existing installation directories -pub mod existing_dirs; - /// Reading patch lists pub mod patchlist;