Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix coordinates sanitization not allowing negative values #37

Merged
merged 3 commits into from
Nov 23, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 121 additions & 43 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,23 @@ impl RustyAutoClickerApp {
Default::default()
}

/// Enter the coordinate setting mode
///
/// # Arguments
///
/// * `frame` - The frame to manipulate
fn enter_coordinate_setting(&mut self, frame: &mut eframe::Frame) {
self.is_setting_coord = true;
self.window_position = frame.info().window_info.position.unwrap();
frame.set_window_size(egui::vec2(400f32, 30f32));
frame.set_decorations(false);
}

/// Make frame follow cursor with an offset
///
/// # Arguments
///
/// * `frame` - The frame to set the window position on
fn follow_cursor(&mut self, frame: &mut eframe::Frame) {
let offset = egui::Vec2 { x: 15f32, y: 15f32 };
frame.set_window_pos(
Expand All @@ -201,13 +211,23 @@ impl RustyAutoClickerApp {
);
}

/// Exit the coordinate setting mode
///
/// # Arguments
///
/// * `frame` - The frame to manipulate
fn exit_coordinate_setting(&mut self, frame: &mut eframe::Frame) {
frame.set_decorations(true);
frame.set_window_size(egui::vec2(WINDOW_WIDTH, WINDOW_HEIGHT));
frame.set_window_pos(self.window_position);
self.is_setting_coord = false;
}

/// Start the autoclicking process
///
/// # Arguments
///
/// * `negative_click_start_offset` - The offset to start the click counter at
fn start_autoclick(&mut self, negative_click_start_offset: u64) {
self.click_counter = 0u64;
self.is_autoclicking = !self.is_autoclicking;
Expand All @@ -219,7 +239,12 @@ impl RustyAutoClickerApp {
}
}

// Provides sanitation for input string
/// Sanitize string
///
/// # Arguments
///
/// * `string` - String to sanitize
/// * `max_length` - Maximum length of string
fn sanitize_string(string: &mut String, max_length: usize) {
// Accept numeric only
let s_slice = string.as_str();
Expand All @@ -232,13 +257,41 @@ fn sanitize_string(string: &mut String, max_length: usize) {
string.remove(0);
}

truncate_string(string, max_length);
}

/// Sanitize string of expected i64 type
///
/// # Arguments
///
/// * `string` - String to sanitize
/// * `max_length` - Maximum length of string
fn sanitize_i64_string(string: &mut String, max_length: usize) {
// Remove leading & trailing whitespaces
// Parse to i64 or return default of 0
*string = string.trim().parse::<i64>().unwrap_or_default().to_string();

truncate_string(string, max_length);
}

/// Truncate string to specified length
///
/// # Arguments
///
/// * `string` - String to be truncated
/// * `max_length` - Maximum length of string
fn truncate_string(string: &mut String, max_length: usize) {
// Allow max size of `max_length` characters
if string.len() >= max_length {
string.truncate(max_length)
};
}

// Simulate event - rdev crate
/// Send the simulated event (`rdev` crate)
///
/// # Arguments
///
/// * `event_type` - The event type to simulate
fn send(event_type: &EventType) {
match simulate(event_type) {
Ok(()) => (),
Expand All @@ -253,6 +306,17 @@ fn send(event_type: &EventType) {
}
}

/// Move the mouse to the specified coordinates
/// Work if app is in "Humandlike" mode only
///
/// # Arguments
///
/// * `app_mode` - The app mode
/// * `click_position` - The click position type
/// * `click_coord` - The click coordinates
/// * `is_moving_humanlike` - Is humanlike mouse movement enabled
/// * `start_coords` - The starting mouse coordinates
/// * `movement_delay_in_ms` - The delay between mouse movements in milliseconds
fn move_to(
app_mode: AppMode,
click_position: ClickPosition,
Expand All @@ -261,52 +325,66 @@ fn move_to(
start_coords: (f64, f64),
movement_delay_in_ms: u64,
) {
if app_mode == AppMode::Humanlike {
if app_mode == AppMode::Humanlike
&& click_position == ClickPosition::Coord
&& is_moving_humanlike
{
// Move mouse slowly to saved coordinates if requested
if click_position == ClickPosition::Coord && is_moving_humanlike {
let mut current_x = start_coords.0;
let mut current_y = start_coords.1;
loop {
// horizontal movement: determine whether we need to move left, right or not at all
let delta_x: f64 = if current_x < click_coord.0 {
MOUSE_STEP_POS_X.min(click_coord.0 - current_x)
} else if current_x > click_coord.0 {
MOUSE_STEP_NEG_X.max(click_coord.0 - current_x)
} else {
0.0
};

// vertical movement: determine whether we need to move up, down or not at all
let delta_y: f64 = if current_y < click_coord.1 {
MOUSE_STEP_POS_Y.min(click_coord.1 - current_y)
} else if current_y > click_coord.1 {
MOUSE_STEP_NEG_Y.max(click_coord.1 - current_y)
} else {
0.0
};

current_x += delta_x;
current_y += delta_y;

#[cfg(debug_assertions)]
println!(
"Moving by {:?} / {:?}, new pos: {:?} / {:?}",
delta_x, delta_y, current_x, current_y
);
send(&EventType::MouseMove {
x: current_x,
y: current_y,
});
let mut current_x = start_coords.0;
let mut current_y = start_coords.1;
loop {
// horizontal movement: determine whether we need to move left, right or not at all
let delta_x: f64 = if current_x < click_coord.0 {
MOUSE_STEP_POS_X.min(click_coord.0 - current_x)
} else if current_x > click_coord.0 {
MOUSE_STEP_NEG_X.max(click_coord.0 - current_x)
} else {
0.0
};

// vertical movement: determine whether we need to move up, down or not at all
let delta_y: f64 = if current_y < click_coord.1 {
MOUSE_STEP_POS_Y.min(click_coord.1 - current_y)
} else if current_y > click_coord.1 {
MOUSE_STEP_NEG_Y.max(click_coord.1 - current_y)
} else {
0.0
};

current_x += delta_x;
current_y += delta_y;

thread::sleep(Duration::from_millis(movement_delay_in_ms));
if current_x == click_coord.0 && current_y == click_coord.1 {
return;
}
#[cfg(debug_assertions)]
println!(
"Moving by {:?} / {:?}, new pos: {:?} / {:?}",
delta_x, delta_y, current_x, current_y
);
send(&EventType::MouseMove {
x: current_x,
y: current_y,
});

thread::sleep(Duration::from_millis(movement_delay_in_ms));
if current_x == click_coord.0 && current_y == click_coord.1 {
return;
}
}
}
}

/// Autoclick the mouse
///
/// # Arguments
///
/// * `app_mode` - The app mode
/// * `click_position` - The click position type
/// * `click_coord` - The click coordinates
/// * `click_type` - The click type
/// * `click_btn` - The click button
/// * `mouse_coord` - The mouse coordinates
/// * `is_moving_humanlike` - Is humanlike mouse movement enabled
/// * `movement_delay_in_ms` - The delay between mouse movements in milliseconds
/// * `rng_thread` - The random number generator thread
#[allow(clippy::too_many_arguments)]
fn autoclick(
app_mode: AppMode,
Expand Down Expand Up @@ -426,8 +504,8 @@ impl eframe::App for RustyAutoClickerApp {
sanitize_string(&mut self.sec_str, 5usize);
sanitize_string(&mut self.ms_str, 5usize);
sanitize_string(&mut self.click_amount_str, 5usize);
sanitize_string(&mut self.click_x_str, 7usize);
sanitize_string(&mut self.click_y_str, 7usize);
sanitize_i64_string(&mut self.click_x_str, 7usize);
sanitize_i64_string(&mut self.click_y_str, 7usize);
sanitize_string(&mut self.movement_sec_str, 5usize);
sanitize_string(&mut self.movement_ms_str, 5usize);

Expand Down