use rand::Rng; use std::{ io::{self, Read, Write}, sync::mpsc, thread, time::Duration, }; // This is a practice program to test if the main programs behaviour works fine // This program has been validated and confirmed to work as expected with scanmem // Structure to hold the "real" game state struct GameState { // Internal values that control the actual game state values: Vec, } // Structure to manage what's displayed on screen struct GameDisplay { // Pointers to copies of values shown to the player display_values: Vec>, } impl GameState { fn new(count: usize, rng: &mut impl Rng) -> Self { let mut values = Vec::with_capacity(count); for _ in 0..count { values.push(rng.gen_range(1..10)); } Self { values } } fn get_value(&self, index: usize) -> i32 { self.values[index] } fn set_value(&mut self, index: usize, value: i32) { self.values[index] = value; } } impl GameDisplay { fn new(count: usize) -> Self { let mut display_values = Vec::with_capacity(count); for _ in 0..count { display_values.push(Box::new(0)); } Self { display_values } } fn update_from_state(&mut self, state: &GameState) { for (i, val) in state.values.iter().enumerate() { *self.display_values[i] = *val; } } fn get_display_ptr(&self, index: usize) -> *const i32 { &*self.display_values[index] as *const i32 } fn get_displayed_value(&self, index: usize) -> i32 { *self.display_values[index] } } fn main() { let mut rng = rand::thread_rng(); const LEN: usize = 10; let mut game_state = GameState::new(LEN, &mut rng); let mut game_display = GameDisplay::new(LEN); game_display.update_from_state(&game_state); let (tx, rx) = mpsc::channel(); thread::spawn(move || { let mut buffer = [0; 1]; loop { if let Ok(_) = io::stdin().read_exact(&mut buffer) { let _ = tx.send(()); } } }); let mut refresh_counter = 0; loop { print!("\x1B[2J\x1B[1;1H"); refresh_counter += 1; if refresh_counter >= 3 { refresh_counter = 0; game_display.update_from_state(&game_state); println!("(Display refreshed from game state)"); } println!( "Memory Scanner Target (Realistic Game Structure) - Press ENTER for new values, Ctrl+C to quit" ); println!("Displayed values (what you see on screen):"); for i in 0..LEN { let display_value = game_display.get_displayed_value(i); let display_ptr = game_display.get_display_ptr(i); println!( "Value {}: {} (displayed at {:p})", i, display_value, display_ptr ); } println!("\nInternal game state (would be hidden in a real game):"); for i in 0..LEN { println!("Value {}: {}", i, game_state.get_value(i)); } println!("\nPress ENTER to change all values..."); io::stdout().flush().unwrap(); if rx.recv_timeout(Duration::from_secs(1)).is_ok() { for i in 0..LEN { game_state.set_value(i, rng.gen_range(1..10)); } game_display.update_from_state(&game_state); refresh_counter = 0; } } }