2022-10-13 15:45:23 -04:00
|
|
|
use std::collections::HashMap;
|
2022-07-27 21:41:05 -04:00
|
|
|
use physis::index;
|
2022-08-16 11:52:07 -04:00
|
|
|
use std::env;
|
2022-10-17 15:03:07 -04:00
|
|
|
use std::path::Path;
|
2022-10-13 15:45:23 -04:00
|
|
|
use std::process::Command;
|
2022-10-17 15:03:07 -04:00
|
|
|
use hmac_sha512::Hash;
|
2022-10-13 15:45:23 -04:00
|
|
|
use physis::installer::install_game;
|
|
|
|
use physis::patch::apply_patch;
|
2022-10-13 16:11:20 -04:00
|
|
|
use walkdir::WalkDir;
|
2022-07-19 19:29:41 -04:00
|
|
|
|
|
|
|
#[test]
|
2022-07-27 20:58:12 -04:00
|
|
|
#[cfg_attr(not(feature = "retail_game_testing"), ignore)]
|
2022-07-19 19:29:41 -04:00
|
|
|
fn test_index_read() {
|
|
|
|
let game_dir = env::var("FFXIV_GAME_DIR").unwrap();
|
|
|
|
|
2022-08-16 11:52:07 -04:00
|
|
|
index::IndexFile::from_existing(
|
|
|
|
format!("{}/game/sqpack/ffxiv/000000.win32.index", game_dir).as_str(),
|
|
|
|
);
|
2022-07-19 19:29:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-07-27 20:58:12 -04:00
|
|
|
#[cfg_attr(not(feature = "retail_game_testing"), ignore)]
|
2022-07-19 19:29:41 -04:00
|
|
|
fn test_gamedata_extract() {
|
|
|
|
let game_dir = env::var("FFXIV_GAME_DIR").unwrap();
|
|
|
|
|
2022-08-16 11:52:07 -04:00
|
|
|
let mut gamedata =
|
|
|
|
physis::gamedata::GameData::from_existing(format!("{}/game", game_dir).as_str()).unwrap();
|
2022-07-19 19:29:41 -04:00
|
|
|
|
|
|
|
gamedata.reload_repositories();
|
|
|
|
|
|
|
|
assert!(gamedata.extract("exd/root.exl").is_some());
|
2022-08-16 11:52:07 -04:00
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
fn make_temp_install_dir(name: &str) -> String {
|
2022-10-13 15:45:23 -04:00
|
|
|
let installer_exe = env::var("FFXIV_INSTALLER").unwrap();
|
|
|
|
|
2022-10-17 15:26:12 -04:00
|
|
|
let mut game_dir = env::home_dir().unwrap();
|
2022-10-17 15:03:07 -04:00
|
|
|
game_dir.push(name);
|
2022-10-13 15:45:23 -04:00
|
|
|
|
|
|
|
if std::fs::read_dir(&game_dir).ok().is_some() {
|
|
|
|
std::fs::remove_dir_all(&game_dir).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::fs::create_dir_all(&game_dir).unwrap();
|
|
|
|
|
|
|
|
install_game(&installer_exe, game_dir.as_path().to_str().unwrap()).ok().unwrap();
|
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
game_dir.as_path().to_str().unwrap().parse().unwrap()
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
fn fill_dir_hash(game_dir: &str) -> HashMap<String, [u8; 64]> {
|
|
|
|
let mut file_hashes : HashMap<String, [u8; 64]> = HashMap::new();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
WalkDir::new(game_dir)
|
|
|
|
.into_iter()
|
|
|
|
.filter_map(Result::ok)
|
|
|
|
.filter(|e| !e.file_type().is_dir())
|
|
|
|
.for_each(|x| {
|
|
|
|
let file = std::fs::read(x.path()).unwrap();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let mut hash = hmac_sha512::Hash::new();
|
|
|
|
hash.update(&file);
|
|
|
|
let sha = hash.finalize();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let mut rel_path = x.path();
|
|
|
|
rel_path = rel_path.strip_prefix(game_dir).unwrap();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
file_hashes.insert(rel_path.to_str().unwrap().to_string(), sha);
|
|
|
|
});
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
file_hashes
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
fn physis_install_patch(game_directory: &str, data_directory: &str, patch_name : &str) {
|
|
|
|
let patch_dir = env::var("FFXIV_PATCH_DIR").unwrap();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let patch_path = format!("{}/{}", patch_dir, &patch_name);
|
|
|
|
let data_dir = format!("{}/{}", game_directory, data_directory);
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
apply_patch(&data_dir, &patch_path).unwrap();
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
fn xivlauncher_install_patch(game_directory: &str, data_directory: &str, patch_name : &str) {
|
|
|
|
let patch_dir = env::var("FFXIV_PATCH_DIR").unwrap();
|
|
|
|
let patcher_exe = env::var("FFXIV_XIV_LAUNCHER_PATCHER").unwrap();
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let patch_path = format!("Z:\\{}\\{}", patch_dir, &patch_name);
|
|
|
|
let game_dir = format!("Z:\\{}\\{}", game_directory, data_directory);
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
// TODO: check for windows systems
|
|
|
|
Command::new("/usr/bin/wine")
|
|
|
|
.args([&patcher_exe,
|
|
|
|
"install",
|
|
|
|
&patch_path,
|
|
|
|
&game_dir])
|
|
|
|
.output()
|
|
|
|
.unwrap();
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
#[test]
|
|
|
|
#[cfg_attr(not(feature = "patch_testing"), ignore)]
|
|
|
|
fn test_patching() {
|
|
|
|
println!("Beginning game installation...");
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let physis_dir = make_temp_install_dir("game_test");
|
|
|
|
let xivlauncher_dir = make_temp_install_dir("game_test_xivlauncher");
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let boot_patches = ["boot/2022.03.25.0000.0001.patch",
|
|
|
|
"boot/2022.08.05.0000.0001.patch"];
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
println!("The game installation is now complete. Now running boot patching...");
|
|
|
|
for patch in boot_patches {
|
|
|
|
xivlauncher_install_patch(&xivlauncher_dir, "boot", patch);
|
|
|
|
physis_install_patch(&physis_dir, "boot", patch);
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:26:12 -04:00
|
|
|
let game_patches =
|
|
|
|
["game/H2017.06.06.0000.0001a.patch",
|
|
|
|
"game/H2017.06.06.0000.0001b.patch",
|
|
|
|
"game/H2017.06.06.0000.0001c.patch",
|
|
|
|
"game/H2017.06.06.0000.0001d.patch",
|
|
|
|
"game/H2017.06.06.0000.0001e.patch",
|
|
|
|
"game/H2017.06.06.0000.0001f.patch",
|
|
|
|
"game/H2017.06.06.0000.0001g.patch",
|
|
|
|
"game/H2017.06.06.0000.0001h.patch",
|
|
|
|
"game/H2017.06.06.0000.0001i.patch",
|
|
|
|
"game/H2017.06.06.0000.0001j.patch",
|
|
|
|
"game/H2017.06.06.0000.0001k.patch",
|
|
|
|
"game/H2017.06.06.0000.0001l.patch",
|
|
|
|
"game/H2017.06.06.0000.0001m.patch",
|
|
|
|
"game/H2017.06.06.0000.0001n.patch",
|
|
|
|
"game/D2017.07.11.0000.0001.patch",
|
2022-10-17 17:48:12 -04:00
|
|
|
"game/D2017.09.24.0000.0001.patch",
|
|
|
|
"ex1/H2017.06.01.0000.0001a.patch",
|
|
|
|
"ex1/H2017.06.01.0000.0001b.patch",
|
|
|
|
"ex1/H2017.06.01.0000.0001c.patch",
|
|
|
|
"ex1/H2017.06.01.0000.0001d.patch"];
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
println!("Boot patching is now complete. Now running game patching...");
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
for patch in game_patches {
|
2022-10-17 15:26:12 -04:00
|
|
|
println!("Installing {}...", patch);
|
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
xivlauncher_install_patch(&xivlauncher_dir, "game", patch);
|
|
|
|
physis_install_patch(&physis_dir, "game", patch);
|
|
|
|
}
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
println!("Game patching is now complete. Proceeding to checksum matching...");
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:03:07 -04:00
|
|
|
let xivlauncher_files = fill_dir_hash(&xivlauncher_dir);
|
|
|
|
let physis_files = fill_dir_hash(&physis_dir);
|
2022-10-13 15:45:23 -04:00
|
|
|
|
2022-10-17 15:36:47 -04:00
|
|
|
for file in xivlauncher_files.keys() {
|
|
|
|
if xivlauncher_files[file] != physis_files[file] {
|
|
|
|
println!("{} does not match!", file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-13 15:45:23 -04:00
|
|
|
assert_eq!(physis_files, xivlauncher_files);
|
|
|
|
}
|