Babylonia-terminal/babylonia-terminal-sdk/src/game_patcher.rs
2024-05-04 19:24:59 +02:00

105 lines
2.7 KiB
Rust

use std::{
io::Read,
path::{Path, PathBuf},
};
use dirs::executable_dir;
use log::debug;
use rust_embed::RustEmbed;
use tokio::{
fs::{remove_file, rename, File},
io::AsyncWriteExt,
};
use crate::{
game_state::GameState,
utils::{get_game_name, get_game_name_with_executable},
};
pub async fn patch_game(game_dir: PathBuf) -> anyhow::Result<()> {
// section to fix bad named file
debug!("{:?}", game_dir);
let unity_resources = game_dir.join(get_game_name()).join(format!(
"{}{}",
get_game_name(),
"_Data/Resources/unity%20default%20resources"
));
debug!("unity resources exist? : {}", unity_resources.exists());
if unity_resources.exists() {
rename(
unity_resources.clone(),
unity_resources
.parent()
.unwrap()
.join("unity default resources"),
)
.await?;
} else if !unity_resources
.parent()
.unwrap()
.join("unity default resources")
.exists()
{
anyhow::bail!(
"{} file doesn't exists ? Please restart the launcher and make a repair.",
unity_resources.to_str().unwrap()
);
}
// section to replace KRSDKExternal.exe by an empty one
//
let krsdk_external_path = game_dir.join(get_game_name()).join(format!(
"{}{}",
get_game_name(),
"_Data/Plugins/KRSDKExternal.exe"
));
remove_file(krsdk_external_path.clone()).await?;
File::create(krsdk_external_path).await?;
// section to replace the executable with the patched one
let executable_path = game_dir
.join(get_game_name())
.join(get_game_name_with_executable());
debug!("{:?}", executable_path);
if executable_path.exists() {
remove_file(executable_path.clone()).await?;
}
match PatchedGameExecutable::get_exectable() {
Some(exe) => {
let mut file = File::create(executable_path).await?;
let data: Result<Vec<_>, _> = exe.data.bytes().collect();
let data = data.expect("Unable to read executable data");
file.write_all(&data).await?;
}
None => anyhow::bail!(
"Game executable not included in the binary! Please report this to the developer!"
),
}
let mut config = GameState::get_config().await;
config.is_game_patched = true;
GameState::save_config(config).await?;
Ok(())
}
#[derive(RustEmbed)]
#[folder = "assets/"]
struct PatchedGameExecutable;
impl PatchedGameExecutable {
fn get_exectable() -> Option<rust_embed::EmbeddedFile> {
PatchedGameExecutable::get("patched.exe")
}
}