From c896bc0562c08a4bc3880884edb0644de6cb3524 Mon Sep 17 00:00:00 2001 From: Frank van der Stam Date: Thu, 20 Oct 2022 19:18:02 +0200 Subject: [PATCH] Added elden ring --- soulmemory-rs/src/app.rs | 12 +- soulmemory-rs/src/games/elden_ring.rs | 110 ++++++++++++++++++ soulmemory-rs/src/games/mod.rs | 8 ++ .../src/games/prepare_to_die_edition.rs | 11 +- 4 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 soulmemory-rs/src/games/elden_ring.rs diff --git a/soulmemory-rs/src/app.rs b/soulmemory-rs/src/app.rs index 9dfa9fb..6e5e5a3 100644 --- a/soulmemory-rs/src/app.rs +++ b/soulmemory-rs/src/app.rs @@ -21,6 +21,7 @@ use imgui::{Condition, Ui, Window}; use crate::games::{Game, GameEnum}; use crate::games::dark_souls_3::DarkSouls3; use crate::games::sekiro::Sekiro; +use crate::games::elden_ring::EldenRing; use crate::games::prepare_to_die_edition::DarkSoulsPrepareToDieEdition; use crate::games::remastered::DarkSoulsRemastered; use crate::gui::event_flags::EventFlagLogger; @@ -67,11 +68,12 @@ impl App //Init the game we're injected in let game: GameEnum = match process_name.to_lowercase().as_str() { - "darksouls.exe" => GameEnum::DarkSoulsPrepareToDieEdition(DarkSoulsPrepareToDieEdition::new()), - "darksoulsremastered.exe" => GameEnum::DarkSoulsRemastered(DarkSoulsRemastered::new()), - "darksoulsiii.exe" => GameEnum::DarkSouls3(DarkSouls3::new()), - "sekiro.exe" => GameEnum::Sekiro(Sekiro::new()), - _ => panic!("unsupported process: {}", process_name.to_lowercase()), + "darksouls.exe" => GameEnum::DarkSoulsPrepareToDieEdition(DarkSoulsPrepareToDieEdition::new()), + "darksoulsremastered.exe" => GameEnum::DarkSoulsRemastered(DarkSoulsRemastered::new()), + "darksoulsiii.exe" => GameEnum::DarkSouls3(DarkSouls3::new()), + "sekiro.exe" => GameEnum::Sekiro(Sekiro::new()), + "eldenring.exe" => GameEnum::EldenRing(EldenRing::new()), + _ => panic!("unsupported process: {}", process_name.to_lowercase()), }; //get drawable widgets diff --git a/soulmemory-rs/src/games/elden_ring.rs b/soulmemory-rs/src/games/elden_ring.rs new file mode 100644 index 0000000..5285110 --- /dev/null +++ b/soulmemory-rs/src/games/elden_ring.rs @@ -0,0 +1,110 @@ +// This file is part of the soulmemory-rs distribution (https://github.com/FrankvdStam/soulmemory-rs). +// Copyright (c) 2022 Frank van der Stam. +// https://github.com/FrankvdStam/soulmemory-rs/blob/main/LICENSE +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use std::mem; +use std::sync::{Arc, Mutex}; +use detour::static_detour; +use log::info; +use mem_rs::prelude::*; +use crate::games::{DxVersion, Game}; +use crate::gui::event_flags::{EventFlag, EventFlagLogger, EventFlagWidget}; +use crate::gui::widget::Widget; + +static_detour!{ static STATIC_DETOUR_SET_EVENT_FLAG: fn(u64, u32, i32); } + +type FnGetEventFlag = fn(event_flag_man: u64, event_flag: u32) -> u8; + +pub struct EldenRing +{ + process: Process, + + event_flags: Arc>>, + event_flag_man: Pointer, + fn_get_event_flag: FnGetEventFlag, +} + +impl EldenRing +{ + pub fn new() -> Self + { + EldenRing + { + process: Process::new("eldenring.exe"), + + event_flags: Arc::new(Mutex::new(Vec::new())), + event_flag_man: Pointer::default(), + fn_get_event_flag: |_,_|{0}, + } + } +} + +impl EventFlagLogger for EldenRing +{ + fn get_buffered_flags(&mut self) -> Vec + { + let mut event_flags = self.event_flags.lock().unwrap(); + mem::replace(&mut event_flags, Vec::new()) + } + + fn get_event_flag_state(&self, event_flag: u32) -> bool { + let result = (self.fn_get_event_flag)(self.event_flag_man.read_u64_rel(None), event_flag); + return result == 1; + } +} + +impl Game for EldenRing +{ + fn refresh(&mut self) -> Result<(), String> { + if !self.process.is_attached() + { + unsafe + { + self.process.refresh()?; + + self.event_flag_man = self.process.scan_rel("SprjEventFlagMan", "48 83 3d ? ? ? ? 00 75 46 4c 8b 05 ? ? ? ? 4c 89 44 24 40 ba 08 00 00 00 b9 c8 01 00 00", 3, 8, vec![0])?; + + let set_event_flag_address = self.process.scan_abs("set_event_flag", "48 89 5c 24 08 44 8b 49 1c 44 8b d2 33 d2 41 8b c2 41 f7 f1 41 8b d8 4c 8b d9", 0, Vec::new())?.get_base_address(); + let get_event_flag_address = self.process.scan_abs("get_event_flag", "44 8b 41 1c 44 8b da 33 d2 41 8b c3 41 f7 f0", 0, Vec::new())?.get_base_address(); + self.fn_get_event_flag = mem::transmute(get_event_flag_address); + + let event_flags = Arc::clone(&self.event_flags); + STATIC_DETOUR_SET_EVENT_FLAG.initialize(mem::transmute(set_event_flag_address), move |rdx: u64, event_flag_id: u32, value: i32| + { + let mut guard = event_flags.lock().unwrap(); + guard.push((chrono::offset::Local::now(), event_flag_id, value == 1)); + STATIC_DETOUR_SET_EVENT_FLAG.call(rdx, event_flag_id, value); + }).unwrap().enable().unwrap(); + + info!("event_flag_man base address: 0x{:x}", self.event_flag_man.get_base_address()); + info!("set event flag address : 0x{:x}", set_event_flag_address); + info!("get event flag address : 0x{:x}", get_event_flag_address); + } + } + else + { + self.process.refresh()?; + } + Ok(()) + } + + fn get_dx_version(&self) -> DxVersion { + DxVersion::Dx12 + } + + fn get_widgets(&self) -> Vec> { + vec![Box::new(EventFlagWidget::new())] + } +} \ No newline at end of file diff --git a/soulmemory-rs/src/games/mod.rs b/soulmemory-rs/src/games/mod.rs index a98679b..b8c22b6 100644 --- a/soulmemory-rs/src/games/mod.rs +++ b/soulmemory-rs/src/games/mod.rs @@ -15,6 +15,7 @@ // along with this program. If not, see . use crate::games::dark_souls_3::DarkSouls3; +use crate::games::elden_ring::EldenRing; use crate::games::prepare_to_die_edition::DarkSoulsPrepareToDieEdition; use crate::games::remastered::DarkSoulsRemastered; use crate::games::sekiro::Sekiro; @@ -25,6 +26,7 @@ pub mod remastered; pub mod prepare_to_die_edition; pub mod dark_souls_3; pub mod sekiro; +pub mod elden_ring; #[allow(dead_code)] pub enum DxVersion @@ -47,6 +49,7 @@ pub enum GameEnum DarkSoulsRemastered(DarkSoulsRemastered), DarkSouls3(DarkSouls3), Sekiro(Sekiro), + EldenRing(EldenRing), } @@ -60,6 +63,7 @@ impl Game for GameEnum GameEnum::DarkSoulsRemastered(remastered) => remastered.refresh(), GameEnum::DarkSouls3(ds3) => ds3.refresh(), GameEnum::Sekiro(sekiro) => sekiro.refresh(), + GameEnum::EldenRing(elden_ring) => elden_ring.refresh(), } } @@ -70,6 +74,7 @@ impl Game for GameEnum GameEnum::DarkSoulsRemastered(remastered) => remastered.get_dx_version(), GameEnum::DarkSouls3(ds3) => ds3.get_dx_version(), GameEnum::Sekiro(sekiro) => sekiro.get_dx_version(), + GameEnum::EldenRing(elden_ring) => elden_ring.get_dx_version(), } } @@ -80,6 +85,7 @@ impl Game for GameEnum GameEnum::DarkSoulsRemastered(remastered) => remastered.get_widgets(), GameEnum::DarkSouls3(ds3) => ds3.get_widgets(), GameEnum::Sekiro(sekiro) => sekiro.get_widgets(), + GameEnum::EldenRing(elden_ring) => elden_ring.get_widgets(), } } } @@ -92,6 +98,7 @@ impl EventFlagLogger for GameEnum { GameEnum::DarkSoulsRemastered(remastered) => remastered.get_buffered_flags(), GameEnum::DarkSouls3(ds3) => ds3.get_buffered_flags(), GameEnum::Sekiro(sekiro) => sekiro.get_buffered_flags(), + GameEnum::EldenRing(elden_ring) => elden_ring.get_buffered_flags(), } } @@ -102,6 +109,7 @@ impl EventFlagLogger for GameEnum { GameEnum::DarkSoulsRemastered(remastered) => remastered.get_event_flag_state(event_flag), GameEnum::DarkSouls3(ds3) => ds3.get_event_flag_state(event_flag), GameEnum::Sekiro(sekiro) => sekiro.get_event_flag_state(event_flag), + GameEnum::EldenRing(elden_ring) => elden_ring.get_event_flag_state(event_flag), } } } \ No newline at end of file diff --git a/soulmemory-rs/src/games/prepare_to_die_edition.rs b/soulmemory-rs/src/games/prepare_to_die_edition.rs index d784527..0e8d504 100644 --- a/soulmemory-rs/src/games/prepare_to_die_edition.rs +++ b/soulmemory-rs/src/games/prepare_to_die_edition.rs @@ -16,10 +16,9 @@ use std::mem; use std::sync::{Arc, Mutex}; -use detour::static_detour; use log::info; use mem_rs::pointer::Pointer; -use mem_rs::prelude::{Process, ReadWrite}; +use mem_rs::prelude::{Process}; use crate::games::{DxVersion, Game}; use crate::gui::event_flags::{EventFlag, EventFlagLogger, EventFlagWidget}; use crate::gui::widget::Widget; @@ -58,7 +57,7 @@ impl EventFlagLogger for DarkSoulsPrepareToDieEdition mem::replace(&mut event_flags, Vec::new()) } - fn get_event_flag_state(&self, event_flag: u32) -> bool + fn get_event_flag_state(&self, _event_flag: u32) -> bool { true //let flag = STATIC_DETOUR_GET_EVENT_FLAG.call(self.event_flag_man.read_u32_rel(None), event_flag); @@ -73,8 +72,8 @@ impl Game for DarkSoulsPrepareToDieEdition { if !self.process.is_attached() { - unsafe - { + //unsafe + //{ self.process.refresh()?; self.event_flag_man = self.process.scan_abs("event flags", "56 8B F1 8B 46 1C 50 A1 ? ? ? ? 32 C9", 8, vec![0, 0])?; @@ -106,7 +105,7 @@ impl Game for DarkSoulsPrepareToDieEdition info!("event_flag_man base address: 0x{:x}", self.event_flag_man.get_base_address()); info!("set event flag address : 0x{:x}", set_event_flag_address); info!("get event flag address : 0x{:x}", get_event_flag_address); - } + //} } else {