~quf/no-cutscene-kiseki

ce548a768925b4a5a152793fde04e2ef1b490fed — Lukas Himbert 10 months ago b6dce0d
clippy
3 files changed, 23 insertions(+), 24 deletions(-)

M src/main.rs
M src/patch.rs
M src/win.rs
M src/main.rs => src/main.rs +6 -6
@@ 68,7 68,7 @@ fn gui_main() {
    );

    let mut folder_select_button = fltk::button::Button::default().with_label("Choose game folder");
    folder_select_button.emit(sender.clone(), Msg::FolderSelect);
    folder_select_button.emit(sender, Msg::FolderSelect);

    flex_row.end();
    flex_row.set_size(&folder_select_button, 150);


@@ 78,10 78,10 @@ fn gui_main() {
    flex_row.set_type(fltk::group::FlexType::Row);

    let mut launch_game_button = fltk::button::Button::default().with_label("Launch Game");
    launch_game_button.emit(sender.clone(), Msg::LaunchGame { exit_after: false });
    launch_game_button.emit(sender, Msg::LaunchGame { exit_after: false });

    let mut launch_game_and_exit_button = fltk::button::Button::default().with_label("Launch Game && Exit");
    launch_game_and_exit_button.emit(sender.clone(), Msg::LaunchGame { exit_after: true });
    launch_game_and_exit_button.emit(sender, Msg::LaunchGame { exit_after: true });
    flex_row.end();
    if install_path.is_some() {
        launch_game_button.activate();


@@ 118,11 118,11 @@ fn gui_main() {
                    }
                }
            }
            Some(Msg::LaunchGame { exit_after }) => match (&install_path).as_ref() {
            Some(Msg::LaunchGame { exit_after }) => match install_path.as_ref() {
                Some(path) => {
                    match identify_version(&path)
                    match identify_version(path)
                        .context("couldn't identify game version")
                        .and_then(|version| run_and_patch(&path, version))
                        .and_then(|version| run_and_patch(path, version))
                        .context("couldn't launch game")
                    {
                        Ok(()) => {}

M src/patch.rs => src/patch.rs +16 -18
@@ 61,8 61,8 @@ pub fn identify_version(base_path: &std::path::Path) -> anyhow::Result<ExeVersio
    let path = base_path.join(exe_path);
    let data = std::fs::read(&path).with_context(|| format!("couldn't read executable file {}", path.display()))?;
    let hash = blake2::Blake2b512::digest(&data);
    for version in known_versions.into_iter().copied() {
        if &hash[..] == version.expected_blake2b_hash() {
    for version in known_versions.iter().copied() {
        if hash[..] == version.expected_blake2b_hash() {
            return Ok(version);
        }
    }


@@ 77,14 77,12 @@ pub fn find_install_path() -> Option<std::path::PathBuf> {
        "Program Files (x86)\\Steam\\steamapps\\common\\The Legend of Heroes Trails of Cold Steel III",
        "SteamLibrary\\steamapps\\common\\The Legend of Heroes Trails of Cold Steel III",
    ];
    let absolute_folders = win::get_drives_with_fallback()
        .map(|drv| {
            let drv = std::path::PathBuf::from(format!("{drv}:\\"));
            paths.map(|path| drv.join(path))
        })
        .flatten();
    let absolute_folders = win::get_drives_with_fallback().flat_map(|drv| {
        let drv = std::path::PathBuf::from(format!("{drv}:\\"));
        paths.map(|path| drv.join(path))
    });
    let relative_folders = ["."].into_iter().map(std::path::PathBuf::from);
    relative_folders.chain(absolute_folders).into_iter().find(|path| path.is_dir() && path.join("bin\\x64").is_dir())
    relative_folders.chain(absolute_folders).find(|path| path.is_dir() && path.join("bin\\x64").is_dir())
}

struct Patch<'a> {


@@ 159,14 157,14 @@ impl SuspendedGameProcess {
        let name = windows::core::HSTRING::from(exe_path);

        let proc_info = win::create_process_w(
            windows::core::PCWSTR(name.as_ptr()),   // name
            windows::core::PWSTR(0 as *mut u16),    // command_line
            None,                                   // process security attributes
            None,                                   // thread security attributes
            false,                                  // inherit handles?
            win::CREATE_SUSPENDED,                  // creation flags
            None,                                   // environment
            windows::core::PCWSTR(0 as *const u16), // working directory
            windows::core::PCWSTR(name.as_ptr()), // name
            windows::core::PWSTR::null(),         // command_line
            None,                                 // process security attributes
            None,                                 // thread security attributes
            false,                                // inherit handles?
            win::CREATE_SUSPENDED,                // creation flags
            None,                                 // environment
            windows::core::PCWSTR::null(),        // working directory
            &startup_info,
        )?;



@@ 209,7 207,7 @@ pub fn run_and_patch(path: &std::path::Path, version: ExeVersion) -> anyhow::Res
    let exe_path = path.join(version.relative_path());
    let exe_data = std::fs::read(&exe_path).context("couldn't check exe data")?;
    let exe_hash = blake2::Blake2b512::digest(&exe_data);
    if &exe_hash[..] != version.expected_blake2b_hash() {
    if exe_hash[..] != version.expected_blake2b_hash() {
        return Err(anyhow::Error::msg("Unexpected executable. Are you sure this is the right version?"));
    }


M src/win.rs => src/win.rs +1 -0
@@ 58,6 58,7 @@ pub unsafe fn write_process_memory(handle: windows::Win32::Foundation::HANDLE, t
    }
}

#[allow(clippy::too_many_arguments)]
pub unsafe fn create_process_w(
    name: windows::core::PCWSTR,
    command_line: windows::core::PWSTR,