mirror of
https://github.com/redstrate/Physis.git
synced 2025-05-05 10:17:45 +00:00
Remove more launcher-only functions from Physis
These are now being moved to the separate Miscel library that can be used standalone with Astra.
This commit is contained in:
parent
75a3eafaf2
commit
cf25a7f91f
3 changed files with 0 additions and 308 deletions
|
@ -1,63 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
|
||||
// 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<String> {
|
||||
let mut needle: Vec<u16> = 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::<Vec<_>>();
|
||||
|
||||
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<String> {
|
||||
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
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
|
||||
// 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<ExistingGameDirectory> {
|
||||
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<ExistingUserDirectory> {
|
||||
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
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue