1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-24 13:37:44 +00:00
physis/src/execlookup.rs

64 lines
1.8 KiB
Rust
Raw Normal View History

// 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) }
}
2024-04-20 13:17:11 -04:00
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);
2024-04-20 13:17:11 -04:00
let mut position = installer_file
.windows(bytes.len())
2024-04-20 13:17:11 -04:00
.position(|window| window == bytes)?;
2024-04-20 13:18:03 -04:00
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
2024-04-20 13:18:03 -04:00
}