ufrisk / MemProcFS

MemProcFS
GNU Affero General Public License v3.0
2.8k stars 352 forks source link

How can I achieve threading with this? (rust) #285

Closed Woah0420 closed 2 months ago

Woah0420 commented 2 months ago

because of the static lifetime of the Vmm structure I cannot pass it to threads so they can create their own scatter handles. is there any way to stop this error?

I know I spelled entities wrong

error[E0597]: fpga does not live long enough --> src\main.rs:55:28 54 let fpga = Arc::new(Vmm::new(vmm_path.as_str(), &vec!["", "-device", "fpga"])?); ---- binding fpga declared here 55 let process = Arc::new(fpga.process_from_name(TARGET_PE)?); ^^^^-----------------------------
borrowed value does not live long enough
argument requires that fpga is borrowed for 'static

... 113 | } | - fpga dropped here while still borrowed

fn entity_cache_loop(scatter_handle: &Arc, base: u64, entity_list: u64, cached_player_list: Arc<Mutex<Vec>>) {

loop {
    let map = game::get_map_name(scatter_handle, base).unwrap();
    {
        let mut cached_player_list = cached_player_list.lock().unwrap();

        if map.contains("mp_lobby") && !cached_player_list.is_empty() {
            cached_player_list.clear();
        }
        else if !map.contains("mp_lobby") && cached_player_list.is_empty() {
            println!("Caching Entities");
            game::cache_entitys(&scatter_handle, entity_list, &String::from("CPlayer"), cached_player_list.as_mut()); 
        }
    }

    thread::sleep(time::Duration::from_secs(1));
}

}

fn entity_loop(cached_player_list: Vec, cached_item_list: Vec) -> Result<u8, anyhow::Error> {

let vmm_path: String;
if let Ok(current_dir) = env::current_dir() {
    let current_dir_str = current_dir.to_str().unwrap(); // returns OPTION
    vmm_path = format!("{}\\vmm.dll", current_dir_str);
} else {
    return Err(anyhow!("C"));
}

let fpga = Arc::new(Vmm::new(vmm_path.as_str(), &vec!["", "-device", "fpga"])?);
let process = Arc::new(fpga.process_from_name(TARGET_PE)?);

let process_addr = process.get_module_base(TARGET_PE)?;
let entity_list = process_addr + offsets::ENTITY_LIST;

let scatter_handle = process.mem_scatter(FLAG_NOCACHE | FLAG_ZEROPAD_ON_FAIL)?;
let scatter_handle = Arc::new(scatter_handle);
let scatter_handle_clone = Arc::clone(&scatter_handle);

println!("name1: {}", game::get_map_name(&scatter_handle_clone, process_addr).unwrap());

let cached_player_list = Arc::new(Mutex::new(cached_player_list));
let mut cached_player_list_clone = Arc::clone(&cached_player_list);

let cached_item_list = Arc::new(Mutex::new(cached_item_list));
let mut cached_item_list_clone = Arc::clone(&cached_item_list);

{
    let mut cached_player_list = cached_player_list.lock().unwrap();
    let mut cached_item_list = cached_item_list.lock().unwrap();
}
println!("name2: {}", game::get_map_name(&scatter_handle_clone, process_addr).unwrap());
let scatter_handle = Arc::new(process.mem_scatter(FLAG_NOCACHE | FLAG_ZEROPAD_ON_FAIL).unwrap());
let scatter_clone = Arc::clone(&scatter_handle);

let s = thread::spawn(move || {
    entity_cache_loop(&scatter_clone, entity_list.clone(), process_addr, cached_player_list_clone)
});

loop {
    let localplayer_addr = memory::scatter_read_as::<u64>(&scatter_handle_clone, process_addr + offsets::LOCAL_PLAYER)?;
    let class_name = game::get_class_name(&scatter_handle_clone, localplayer_addr)?;

    thread::sleep(time::Duration::from_secs(1));
}

s.join();

return Ok(0);

}

fn main() { let cached_player_list = Vec::::new(); let cached_item_list = Vec::::new();

thread::scope(|s| {
    s.spawn( || {
        let _ = entity_loop(cached_player_list, cached_item_list);
    });

    let _ = menu_main();
});
ufrisk commented 2 months ago

I assume you'd also asked the same question at Discord and got a quicker answer? Since you closed I assume that answer resolved your issue?

Is this a decent enough way to resolve this issue, or would you prefer me to add a duplicate() method on the Vmm struct? That way it would be simplified a bit further and you'd be able to pass on the ownership of the newly created Vmm object to your other thread? Or is the current way of doing things decent enough?